[英]Python Why am I getting not defined error?
当我在类代码块中使用任何类变量时,出现未定义的错误。 我该如何解决?
例
class A():
__hidden_number__ = 5
__no_hidden_number__ = A.__hidden_number__ + 4 # to cause error. why ?
谢谢。
您的类变量已经在A
名称空间中。
因此,您只需要执行以下操作:
__no_hidden_number__ = __hidden_number__ + 4
否则,您正在尝试访问AA
,但它尚不存在。
为了说明我在说什么,“有效”(但不是您想要的):
class A():
class A():
__hidden_number__ = 4
__no_hidden_number__ = A.__hidden_number__ + 4
A() # that works
那不是:
class A():
class B():
__hidden_number__ = 4
__no_hidden_number__ = A.__hidden_number__ + 4 # B.__... would've worked
A() # beeep: NameError: name 'A' is not defined
请注意,您应避免使用尾随双下划线( __xxx__
)定义私有属性。 它可以工作,但是通常保留给python特殊类成员( __class__
, __file__
__class__
, __file__
__eq__
等)。 名称修饰(使对象成为“私有”)已经发生了2个下划线。
由于这可能还不清楚(现有答案很好),所以让我补充一点:
class A:
pass
A = type('A', (object,), {})
我们在类声明中编写的内容本质上是在构建该字典(此处为空),并且在分配变量A
之前发生。 而且由于在类声明运行时在命名空间层次结构中尚有一个尚未命名的变量A
,因此A
不可用。
该类存在,它的类型名称也为 'A'
,但尚未将其分配给变量A
class A: pass
-version和显式type
调用之间的区别是语法糖:使用class
,嵌套在class
中的所有内容都会自动命名为类字典。
这就是为什么这样做的原因:
class A:
var = 1
var2 = var + 1
但是正如我们在上面看到的那样,只有在对类声明进行了评估之后,才分配最终将容纳我们的新类的局部变量A
,因此该变量A
其内部不可用。
如果我们反汇编一个class decl,我们将得到:
import codeop, dis
dis.disassemble(codeop.compile_command('class A:\r\n pass'))
1 0 LOAD_CONST 0 ('A')
3 LOAD_CONST 3 (())
6 LOAD_CONST 1 (<code object A at 0x80076ff30, file "<input>", line 1>)
9 MAKE_FUNCTION 0
12 CALL_FUNCTION 0
15 BUILD_CLASS
16 STORE_NAME 0 (A)
19 LOAD_CONST 2 (None)
22 RETURN_VALUE
由于代码对象必须返回一个值,因此会自动添加19
和22
。 对于我们的示例,我们可以忽略它们。
这里还发生了什么?
0
:将字符串'A'
入堆栈。 这将成为类的名称( type()
的第一个参数)。 3
:推送一个空的元组,父类列表 6
:加载用于类声明的代码对象。 9
和12
运行类声明代码对象。 例如,这就是我们的(类)变量分配。 它返回类字典。 15
将类构建到堆栈上。 这等效于type('A', (), class_dict)
,其中参数恰好是此时堆栈上的值。 最后:
16
将新创建的类以名称A
存储到本地名称空间中。 如我们所见,在将类分配给变量A
( 16
)之前,运行类声明( 12
)。
请注意,反汇编在Python 3中有所不同,因为python作为特殊的内置类builder函数 。
是的,答案太长了;-)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.