孙子继承自 Parent class - Python

Grandchild inheriting from Parent class - Python

我正在学习有关 Python classes 的所有知识,而且我有很多基础知识要涵盖。 我遇到了一个让我有点困惑的例子。

这些是 parent classes

Class X
Class Y
Class Z

Child class是:

Class A (X,Y)
Class B (Y,Z)

孙子 class 是:

Class M (A,B,Z)

难道Class M不是通过继承Class B来继承Class Z吗,或者为什么会出现这种结构? Class M 会忽略第二次 Class Z 是继承的,不是吗,还是我遗漏了什么?

Class M would just inherit the Class Z attributes twice (redundant) wouldn't it be, or am I missing something?

不,没有 "duplicated" 属性,Python 执行 线性化 他们可以 方法解析顺序 (MRO) 原样,例如,解释 。但是你是对的,这里添加 Z 到列表不会改变任何东西。

他们首先为 parents 构建 MRO,因此:

MRO(X) = (X,object)
MRO(Y) = (Y,object)
MRO(Z) = (Z,object)

MRO(A) = (A,X,Y,object)
MRO(B) = (B,Y,Z,object)

然后他们通过合并为 M 构造一个 MRO:

MRO(M) = (M,)+merge((A,X,Y,object),(B,Y,Z,object),(Z,object))
       = (M,A,X,B,Y,Z,object)

现在每次调用一个方法时,Python会先检查该属性是否在那个object)[=59的内部字典self.__dict__中=].否则,Python 将 遍历 MRO 并尝试查找具有该名称的属性。从找到的那一刻起,它就会停止搜索。

最后 super() 是一个 proxy-object,它执行相同的分辨率,但在 class 阶段开始于 MRO。所以在这种情况下,如果你有:

class B:

    def foo():
        super().bar()

然后你构建一个 object m = M() 并调用 m.foo() 然后 - 如果调用 Bfoo()super().bar 将首先尝试在 Y 中查找 bar,如果失败,它将在 Z 中查找 bar,最后在 object.[=36= 中查找]

属性继承两次。如果您添加如下属性:

self.qux = 1425

然后它被简单地添加到 object 的内部 self.__dict__ 字典中。

然而,明确说明 Z 可能是有益的:如果 B 的设计者不确定 Z 是否是真正的要求。在那种情况下,如果 B 被更改,您肯定知道 Z 仍将在 MRO 中。

除了@Willem 提到的,我想补充一点,你说的是多重继承问题。对于 python,对象实例化与 Java 等其他语言相比有点不同。这里,对象实例化分为两部分:- 对象创建(使用 __new__ 方法)和对象初始化(使用 __init__ 方法)。此外,子 class 不一定总是具有父 class 的属性。子 class 获取父 class 的属性,仅当从子 class(显式)调用父 class 构造函数时。

>>> class A(object): 
      def __init__(self): 
         self.a = 23
>>> class B(A): 
      def __init__(self): 
         self.b = 33
>>> class C(A): 
      def __init__(self): 
         self.c = 44 
         super(C, self).__init__()
>>> a = A()
>>> b = B()
>>> c = C()
>>> print (a.a) 23
>>> print (b.a) Traceback (most recent call last):   File "<stdin>", line 1, in <module> AttributeError: 'B' object has no attribute 'a'
>>> print (c.a) 23

在上面的代码片段中,B 没有调用 A 的 __init__ 方法,因此它没有 a as 成员变量,尽管它继承自 A class。对于像 Java 这样的语言,情况并非如此,其中有一个固定的属性模板,而 class 将具有。这就是 python 与其他语言的不同之处。

对象拥有的属性,存储在对象的__dict__成员中,它是对象class中的__getattribute__魔术方法,根据实现属性查找mro 由 willem 指定。您可以使用 vars()dir() 方法来自省实例。