【问题标题】:Python class inheritance and __dict__ lookup [duplicate]Python类继承和__dict__查找[重复]
【发布时间】:2014-06-25 03:30:46
【问题描述】:

假设我定义了 A 类:

>>> class A:
...     a = 1
...     class SubA:
...         sub_a = { 'a': 1, 'b': 1}

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

>>> class B(A):
...     pass

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

>>> A.__dict__
{'a': 1, '__module__': '__builtin__', '__doc__': None, 'SubA': <class __builtin_ _.SubA at 0x02CAA3E8>}
>>> B.__dict__
{'__module__': '__builtin__', '__doc__': None}

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

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

>>> A.SubA
<class __builtin__.SubA at 0x02CAA3E8>
>>> B.SubA
<class __builtin__.SubA at 0x02CAA3E8>

第一个问题:为什么B.__dict__不包含'a'和'SubA'? 第二个问题:为什么 Ba 和 B.SubA 给出了预期的结果,虽然 'a' 和 'SubA' 都不在 B 的__dict__?

谢谢!

【问题讨论】:

  • 基本上它首先尝试解析子类中的名称,然后是它的每个超类,然后是每个超类的超类等,直到它解决或者它没有......至少我认为会发生这种情况

标签: python class oop inheritance


【解决方案1】:

@bgporter 已经给出了a good explanation of the behaviour,我将简单介绍一下为什么:

如果您的类变量在B.__dict__ 中,它将如何工作?每个子类都有自己的 a 值,独立于 A.a 的值 - 这不是您所期望的。一个类变量应该存在一次 - 在那个类中。

相反,Python 会查找类,如果不存在,则查找其基类 - 请注意,这意味着可以在子类中隐藏类变量。

【讨论】:

  • 好点。现在,如果我想覆盖班级成员: B.a=2 完成了这项工作,现在 B.__dict__ 有'a'。但是,B.SubA.sub_a = A.SubA.sub_a.copy() 没有帮助,因为如果我更新 B.SubA.sub_a,A.SubA.sub_a 也会更新。是因为必须在此之前覆盖 SubA 吗?
  • 是的。 B.SubA 和 A.SubA 在这种情况下是一样的。一般来说,内部类型在 Python 中很少见,因为它们没有提供太多功能或价值。
  • 我发现有时你可能需要使用它,比如在 Django ModelForms 中,当你有一个 Meta 子类并且你想覆盖它的成员时。
【解决方案2】:

这就是 Python 的 object model 的工作原理:

一个类有一个由字典对象实现的命名空间。班级 属性引用被翻译成这本词典中的查找, 例如,C.x 被翻译成C.__dict__["x"](虽然对于新式 特别是类有许多钩子允许 其他定位属性的方法)。当属性名称不是 在那里找到,属性搜索继续在基类中。

【讨论】:

  • dir(B) 会显示父类属性
猜你喜欢
  • 2013-06-17
  • 2016-07-24
  • 1970-01-01
  • 1970-01-01
  • 2020-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多