"破坏"中的多重继承钻石

时间:2016-07-07 11:25:07

标签: python python-3.x

我正在探索在(两个)父类之一不从公共基类继承的情况下多重继承可能如何工作。这是程序:

'''Demomstration of MRO on 'broken' diamonds'''

class Base:
    def hello(self):
        print('Base')

class Left(Base):
    def hello(self):
        print('Left')
        super().hello()

class Right:
    def hello(self):
        print('Right')
        super().hello()

class Child1(Left, Right):
    '''Class has right edge missing'''
    def hello(self):
        print('Child1')
        super().hello()

class Child2(Right, Left):
    '''Class has left edge missing'''
    def hello(self):
        print('Child2')
        super().hello()

print(help(Child1))
print(help(Child2))

print('Child1 output:')
print('==============')
Child1().hello()
print('\nChild2 output:')
print('==============')
Child2().hello()

help()表示在第一种情况下,MRO将是:

 |      Child1
 |      Left
 |      Base
 |      Right
 |      builtins.object

虽然在第二种情况下它会(请小心点:Right实际上在这里的左侧):

 |      Child2
 |      Right
 |      Left
 |      Base
 |      builtins.object

hello()函数的输出是:

Child1 output:
==============
Child1
Left
Base

Child2 output:
==============
Child2
Right
Left
Base

所以在第一种情况下,Right类已被完全跳过!这几乎就像翻译无法联系到它,因为没有任何关联可以跟随。

我可以理解这可以通过C3线性化算法来解释,但是在镜像图像的情况下,它没有被遗漏,并不是有点奇怪。吨?

1 个答案:

答案 0 :(得分:2)

关于此测试,您的Base.hello功能已“损坏”。考虑MRO中的hello函数:

Child1.hello
    print('Child1')  # PRINTED
    super().hello()  # super() -> Left
Left.hello
    print('Left')    # PRINTED
    super().hello()  # super() -> BASE
Base.hello
    print('Base')  # PRINTED
    # no call to super()!!!
Right.hello    # NEVER CALLED
    print('Left')
    super().hello()  # super() -> object
builtins.object.hello

基本上,一旦super().hello解析为Base.hellosuper链就会停止。 Base.hello错过了对super的调用以前往Right。因此,即使Right.hello位于MRO中,也不会调用Right