python中的内部类评估顺序

时间:2017-12-08 17:46:20

标签: python class inner-classes operator-precedence

假设我在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)

也有效。

为什么内部类定义不遵循与其他所有内容相同的逻辑规则?

1 个答案:

答案 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!'