Python 继承顺序

class Base:
    def __init__(self):
        print('Base.__init__')

class A(Base):
    def __init__(self):
        super().__init__()
        print('A.__init__')

class B(Base):
    def __init__(self):
        super().__init__()
        print('B.__init__')

class C(A,B):
    def __init__(self):
        super().__init__()  # Only one call to super() here
        print('C.__init__')

执行c = C()会输出什么?

>>> c = C()
Base.__init__
B.__init__
A.__init__
C.__init__
>>>

按照MRO列表顺序继承,就理解了。

>>> C.__mro__
(, , ,
, )

“super() 有个令人吃惊的地方是它并不一定去查找某个类在MRO中下一个直接父类”

class A:
    def spam(self):
        print('A.spam')
        super().spam()

如果你试着直接使用这个类就会出错:

>>> a = A()
>>> a.spam()
A.spam
Traceback (most recent call last):
    File "", line 1, in 
    File "", line 4, in spam
AttributeError: 'super' object has no attribute 'spam'
>>>

但是,如果你使用多继承的话看看会发生什么:

>>> class B:
...     def spam(self):
...         print('B.spam')
...
>>> class C(A,B):
...     pass
...
>>> c = C()
>>> c.spam()
A.spam
B.spam
>>>

你可以看到在类A中使用 super().spam() 实际上调用的是跟类A毫无关系的类B中的 spam() 方法。 这个用类C的MRO列表就可以完全解释清楚了:

>>> C.__mro__
(, , ,
)
>>>

参考: https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p07_calling_method_on_parent_class.html

你可能感兴趣的:(Python 继承顺序)