类 中的内部评估顺序 python
Inner classes evaluation order in python
假设我在 python 3.6:
中这样做
class A:
class B:
pass
class C:
x = B()
在 C
中实例化时抱怨 B
未定义,这失败了。
然而,这:
class A:
x = 1
y = x
def f(self):
return self
z = f
工作正常。
当然还有这个:
class A:
pass
class B:
x = A()
也有效。
为什么内部 类 定义不遵循与其他所有内容相同的逻辑规则?
这里的问题不是定义顺序,它像其他所有东西一样工作,而是 class-body 作用域的特殊性质。本质上,class-body 作用域中的变量只能使用 class- 命名空间访问,例如MyClass.my_class_variable
。它的特殊之处在于它不会创建封闭范围,这就是为什么您无法访问 my_class_variable
并且被迫在方法定义中使用 class- 名称空间的原因。详细了解 in this answer。所以, B
实际上已经定义了。注意,以下作品:
In [4]: class A:
...: class B:
...: pass
...: x = B.__name__
...:
...:
In [5]: A.x
Out[5]: 'B'
现在,您可能希望以下方法有效:
In [6]: class A:
...: class B:
...: pass
...: class C:
...: x = A.B()
...:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-1-a145c80eee84> in <module>()
----> 1 class A:
2 class B:
3 pass
4 class C:
5 x = A.B()
<ipython-input-1-a145c80eee84> in A()
2 class B:
3 pass
----> 4 class C:
5 x = A.B()
6
<ipython-input-1-a145c80eee84> in C()
3 pass
4 class C:
----> 5 x = A.B()
6
然而,它并没有,因为A
实际上还没有被定义!所以,解决方案是这样的:
In [7]: class A:
...: class B:
...: pass
...: class C:
...: pass
...:
...:
In [8]: A.C.x = A.B
已编辑
所以,这个例子应该很有启发性:
In [14]: x = 'global'
In [15]: class Foo:
...: x = 'foooooo!'
...: def bar(self):
...: return x
...:
In [16]: Foo().bar()
Out[16]: 'global'
In [17]: Foo.x
Out[17]: 'foooooo!'
假设我在 python 3.6:
中这样做class A:
class B:
pass
class C:
x = B()
在 C
中实例化时抱怨 B
未定义,这失败了。
然而,这:
class A:
x = 1
y = x
def f(self):
return self
z = f
工作正常。
当然还有这个:
class A:
pass
class B:
x = A()
也有效。
为什么内部 类 定义不遵循与其他所有内容相同的逻辑规则?
这里的问题不是定义顺序,它像其他所有东西一样工作,而是 class-body 作用域的特殊性质。本质上,class-body 作用域中的变量只能使用 class- 命名空间访问,例如MyClass.my_class_variable
。它的特殊之处在于它不会创建封闭范围,这就是为什么您无法访问 my_class_variable
并且被迫在方法定义中使用 class- 名称空间的原因。详细了解 in this answer。所以, B
实际上已经定义了。注意,以下作品:
In [4]: class A:
...: class B:
...: pass
...: x = B.__name__
...:
...:
In [5]: A.x
Out[5]: 'B'
现在,您可能希望以下方法有效:
In [6]: class A:
...: class B:
...: pass
...: class C:
...: x = A.B()
...:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-1-a145c80eee84> in <module>()
----> 1 class A:
2 class B:
3 pass
4 class C:
5 x = A.B()
<ipython-input-1-a145c80eee84> in A()
2 class B:
3 pass
----> 4 class C:
5 x = A.B()
6
<ipython-input-1-a145c80eee84> in C()
3 pass
4 class C:
----> 5 x = A.B()
6
然而,它并没有,因为A
实际上还没有被定义!所以,解决方案是这样的:
In [7]: class A:
...: class B:
...: pass
...: class C:
...: pass
...:
...:
In [8]: A.C.x = A.B
已编辑
所以,这个例子应该很有启发性:
In [14]: x = 'global'
In [15]: class Foo:
...: x = 'foooooo!'
...: def bar(self):
...: return x
...:
In [16]: Foo().bar()
Out[16]: 'global'
In [17]: Foo.x
Out[17]: 'foooooo!'