假设我在python 3.6中执行此操作:
class A:
class B:
pass
class C:
x = B()
在B
中实例化C
时,抱怨没有定义class A:
x = 1
y = x
def f(self):
return self
z = f
。
但是,这个:
class A:
pass
class B:
x = A()
工作正常。
当然,这是:
Browser(?:_type)
也有效。
为什么内部类定义不遵循与其他所有内容相同的逻辑规则?
答案 0 :(得分:3)
这里的问题不是定义顺序,它与其他一切一样,它是类体范围的特殊性质。实质上,类 - 体范围中的变量只能使用类命名空间来访问,例如MyClass.my_class_variable
。它的特殊之处在于它不会创建一个封闭范围,这就是为什么你不能访问my_class_variable
并被迫在方法定义中使用class-namespace的原因。详细了解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!'