为什么一个 class-inside-a-class 不在另一个 class-inside-a-class 的范围内?

Why is one class-inside-a-class not in the scope of another class-inside-a-class?

考虑以下代码:

from enum import Enum

class A(object):
    class B(object):
        blah = "foo"
        derp = "bar"

    class SubA(object):
        def __init__(self):                                                                                                                                                                                                            
            self.value = B.derp

这引发了 NameError

>>> A.SubA()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "test.py", line 10, in __init__
    self.value = B.derp
NameError: name 'B' is not defined

另一方面,将 B.derp 替换为 A.B.derp 可使代码按预期工作。

为什么 Python 的范围界定会以这种方式解决这个问题,为什么 应该 这在 Python 的设计中有意义?

PEP 227 中所述,class 主体的作用域在嵌套在其中的其他作用域内不可用。因此,在您的示例中获得 B 的 NameError 的原因与在这种情况下获得 NameError 的原因相同:

class Foo(object):
    x = 88
    def foo(self):
        print(x)

class 主体中定义的函数(即方法)无法访问 class 主体范围;嵌套的 classes(或嵌套在其中的函数)也不行。

A.B.derp 有效是因为 Aglobal 范围内,它总是可以访问的。

但是,请注意,如果您尝试直接在 class 正文中使用它,即使 A.B.derp 也不起作用:

class A(object):
    class B(object):
        derp = 88
    class SubA(object):
        stuff = A.B.derp

这不行,因为引用A.B.derp的行是在创建A的过程中执行的,所以A还不存在,无法引用.

虽然 类 定义了一个新的命名空间,但它们不会为方法体内使用的名称创建范围。在引用它们时,名称必须是完全限定的。 self.somethingcls.something 的用途。

尝试使用像 A.B.something 这样的完全限定名称。 AB 在同一个命名空间,但不在同一个变量范围内。