Python类继承和__dict__查找

jaz*_*lue 3 python oop inheritance class

假设我定义了A类:

>>> class A:
...     a = 1
...     class SubA:
...         sub_a = { 'a': 1, 'b': 1}
Run Code Online (Sandbox Code Playgroud)

然后我定义继承自A的B类:

>>> class B(A):
...     pass
Run Code Online (Sandbox Code Playgroud)

现在,检查__dict__ A和__dict__ B的:

>>> A.__dict__
{'a': 1, '__module__': '__builtin__', '__doc__': None, 'SubA': <class __builtin_ _.SubA at 0x02CAA3E8>}
>>> B.__dict__
{'__module__': '__builtin__', '__doc__': None}
Run Code Online (Sandbox Code Playgroud)

不知何故,B .__ dict__既不包含'a'也不包含'SubA'.现在如果我们这样做:

>>> A.a
1
>>> B.a
1

>>> A.SubA
<class __builtin__.SubA at 0x02CAA3E8>
>>> B.SubA
<class __builtin__.SubA at 0x02CAA3E8>
Run Code Online (Sandbox Code Playgroud)

第一个问题:为什么B .__ dict__不包含'a''SubA'?第二个问题:为什么Ba和B.SubA产生预期的结果,虽然没有"一",也没有"速霸"是在__dict__

谢谢!

Gar*_*tty 7

@bgporter给行为的一个很好的解释,我就进入为什么一点:

如果你的类变量在B.__dict__,它将如何运作?每个子类都有自己的值a,与值无关A.a- 这不是你所期望的.类变量应该存在一次 - 在该类中.

相反,Python对类进行查找,如果它不存在,则查找它的基类 - 注意这意味着可以在子类中隐藏类变量.


bgp*_*ter 5

这就是Python的对象模型的工作原理:

类具有由字典对象实现的命名空间.类属性引用被转换为该字典中的查找,例如,C.x被转换为C.__dict__["x"](尽管对于新式类,特别是存在许多允许其他方法来定位属性的钩子).当在那里找不到属性名称时,属性搜索在基类中继续.

  • `dir(B)`会显示父类属性 (3认同)