为什么__base__在类正文中不可访问?

Ara*_*Fey 6 python inheritance class

类对象具有__bases__(和__base__)属性:

>>> class Foo(object):
...     pass
... 
>>> Foo.__bases__
(<class 'object'>,)
Run Code Online (Sandbox Code Playgroud)

遗憾的是,这些属性无法在类主体中访问,这对于访问父类属性非常方便,而无需硬编码名称:

class Foo:
    cls_attr = 3

class Bar(Foo):
    cls_attr = __base__.cls_attr + 2
    # throws NameError: name '__base__' is not defined
Run Code Online (Sandbox Code Playgroud)

有没有为什么原因__bases____base__不能在类体内进行访问?

(要清楚,我要问的是这是一个有意识的设计决定。我不是在问实现;我知道这__bases__是其中的一个描述符,type并且在创建类对象之前无法访问此描述符。我想知道为什么python没有__bases__在类体中创建为局部变量。)

bru*_*ers 6

我想知道为什么python __bases__在类体中没有创建为局部变量

如您所知,class它通常是一种快捷方式type.__new__()-当运行时命中class语句时,它会在class主体的顶层执行所有语句,在专用的命名空间dict中收集所有结果绑定,并type()使用具体的元类,类名进行调用,基类和名称空间字典,并将结果类对象绑定到封闭范围内的类名称(通常但不一定是模块的顶级名称空间)。

这里的重点是,构建类对象并允许自定义类对象的创建是元类的责任,元类必须可以自由地对其参数进行任何操作。通常,自定义元类将主要对attrsdict 起作用,但是它也必须能够弄乱bases参数。现在,由于仅在执行了类主体语句之后才调用元类,因此运行时无法可靠地bases在类主体范围中公开,因为这些基可以由元类随后进行修改。

这里还有更多哲学上的考虑,特别是wrt / explicit和隐式,并且如shx2所提到的,Python设计人员试图避免魔术变量突然出现。实际上,确实有几个实现变量(__module__在py3中__qualname__)是在类主体名称空间中“自动”定义的,但它们只是名称,主要用于为开发人员提供其他调试/检查信息,并且对变量没有任何影响。类对象的创建或其属性,行为和其他内容。

与Python一样,您必须考虑整个上下文(执行模型,对象模型,不同部分如何协同工作等),才能真正理解设计选择。您是否同意整个设计和哲学是另一个争论(并且不属于这里),但是您可以肯定的是,这些选择 “有意识的设计决定”。