Python 3.x: 文件中的 class 无法在同一文件中找到另一个 class

Python 3.x: class in file can't locate another class in the same file

我需要一些帮助来解决 NameError。值得注意的是,我在 Autodesk Maya 2017 中执行此代码。

这是问题的概述:我无法在与我正在使用的 class 相同的文件中创建 class 的对象。因此,如果我定义 class foo() 和一个 class foobar(),在 class foo() 中,我尝试通过输入 foobarObj = foobar() 创建一个 class foobar() 的对象,我得到一个 nameError,指出 foobar 未定义。
示例代码:

class foo:
    foobarObj = foobar # crashes here (nameError: foobar is not defined)
    __init__():
       pass
class foobar:
    fooObj = foo # crashes here as well
    __init__():
       pass

我完全有可能不了解 python 中的 OOP,并且我的错误在该示例代码中很明显。我不确定是否需要在 foo 之前定义 foobar?如果是这样,我怎样才能使代码工作?我需要在第二个 class 中创建第一个 class 的对象,而且在第一个 class 中创建第二个 class 的对象(这可能是问题所在,因为 python 不知道第二个 class 已经被定义,当我试图在第一个 class? 中创建一个对象时。

This thread 似乎解决了一个类似的问题,如果不是同一个问题,但我真的不明白其中发生了什么或提供的答案,因为它是 Django 特有的。

但是,如果我提供的示例代码看起来 'kosher',这里有更多信息,我的实际代码是 运行:

我的实际项目中有三个文件,createUI.py调用一个函数创建一个新的window,suite_modules.py包含程序的方法UI, bb_modules.py 包含两个 classes 和 UI 方法和基本命令方法。当我尝试在基本命令 class 中创建 UI class 的对象时,bb_modules.py 文件中出现错误。

createUI.py # 这是执行的第一个脚本,它导入第二个脚本 suite_modules

# createUI.py #
import os
import maya.cmds as cmds

# store the user's script directory as variable 'usd'
usd = cmds.internalVar(usd=True)

# prep the import path
bb_modules = 'suite_modules'
bb_modules = os.path.join(usd, bb_modules)
# import the module
import suite_modules
reload (suite_modules)

# create a new window
def createFloatingWin():
    UI = suite_modules.SuiteUIcommands()
    UI.createBuddySuiteUIWindow()

suite_modules.py # 这是第一个脚本导入的模块。它导入名为 bb_modules.py

的第三个模块
# suite_modules.py #
### Imports and script properties ###
import maya.cmds as cmds
import os
class SuiteUIcommands():
# Imports
# store the user's script directory as variable 'usd'
usd = cmds.internalVar(usd=True)
# Prep the file path for bb_modules
bb_modules = 'bb_modules'
bb_modules = os.path.join(usd, bb_modules)

# Import batch buddy commands
import bb_modules
reload (bb_modules)
# there is more to the script but it is not relevant, 
# the execution crashes during this import

bb_modules.py # 这是执行崩溃的地方,在从 suite_modules

导入期间
# bb_modules.py #
import maya.cmds as cmds
import os
import maya.mel as mel

class BBbatchCommands:
    # Define Variables
    # Get the UIcommands
    BBUI = BBUIcommands() # THE CRASH HAPPENS HERE #

    def __init__(self):
        self.uselessVariable = 0

    # there is more to the class but it never gets that far

class BBUIcommands:
    # Import the other module in this file, the batch commands
    BBcmd = BBbatchCommands() # THE CRASH HAPPENS HERE IF 
    # THE CLASSES ARE DEFINED IN REVERSE

    def __init__(self):
        pass

    # as usual, there is more to the class but it isn't relevant

最后是 Maya 输出的完整堆栈跟踪:

# Error: line 1: name 'BBUIcommands' is not defined
# Traceback (most recent call last):
#   File "<maya console>", line 1, in <module>
#   File 
"C:/Users/censored/Documents/maya/2017/scripts\BuddySuite.py", line 21, in <module>
#     import suite_modules
#   File 
"C:/Users/censored/Documents/maya/2017/scripts\suite_modules.py", line 22, in <module>
#     class SuiteUIcommands():
#   File 
"C:/Users/censored/Documents/maya/2017/scripts\suite_modules.py", line 31, in SuiteUIcommands
#     import bb_modules
#   File 
"C:/Users/censored/Documents/maya/2017/scripts\bb_modules.py", line 13, in <module>
#     class BBbatchCommands:
#   File 
"C:/Users/censored/Documents/maya/2017/scripts\bb_modules.py", line 16, in BBbatchCommands
#     BBUI = BBUIcommands()
# NameError: name 'BBUIcommands' is not defined #`

任何帮助将不胜感激,干杯!

问题是顶层Python代码还有class主体是顺序执行的首次导入模块时。引用任何尚未定义的名称将引发 NameError

一个简单的解决方案是推迟分配:

class BBbatchCommands:
    def __init__(self):
        self.uselessVariable = 0

class BBUIcommands:
    BBcmd = BBbatchCommands()

BBbatchCommands.BBUI = BBUIcommands()

没有崩溃!

但是,代码仍然有奇怪的味道,这种循环依赖对我来说不合适。

class 中的所有内容实际上都是 python 幕后的一个模块,因此它实际上是在解析脚本时执行的,就像您执行导入一样。

在 class 主体中定义变量时,您定义的是一个静态变量,它将在 class 的所有实例之间共享。只要我们得到我们正在寻找的行为,这就完全没问题。 类 作为变量的简单名称空间也很正常。

为了说明区别:

静态变量:

class Batch:
    commands = []

a = Batch()
b = Batch()
a.commands.append("a")
b.commands.append("b")
print(a.commands)
print(b.commands)

将打印:

['a', 'b']
['a', 'b']

实例变量:

class Batch:
    def __init__(self):
        self.commands = []

a = Batch()
b = Batch()
a.commands.append("a")
b.commands.append("b")
print(a.commands)
print(b.commands)

将打印:

['a']
['b']

如果您要制作多个 BBbatchCommands class 实例,我会担心。

__init__() 中设置的所有内容对于实例都是唯一的。