具有多重继承的Python中的调用解析顺序

Call resolution order in Python with multiple inheritance

我在YouTube上看了一个关于Python的演讲,发现了一个有趣的语言特性。但是,当我试图运行一个测试代码时,它不起作用,我想知道为什么。

我希望这个能打印出来:

1
2
Parent
OtherParent

但是我得到了这个:

1
2
Parent
Parent

样本代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Parent:
    def get_message(self):
        return"Parent"

class Child(Parent):
    def do_print(self):
        print(super().get_message())

class OtherParent:
    def get_message(self):
        return"OtherParent"

class OtherChild(Child, OtherParent):
    pass

Child().do_print()
OtherChild().do_print()

编辑:在Windows上运行,python 3.5.1,anaconda 4.0.0(64位)


问题的注释中提到了正确的解释,即来自OtherChild类的mro(注释中发布的链接:mixin的顺序如何影响派生类?).

根据不同的继承,可以看到OtherChild类的mro的不同输出:

  • OtherParent没有父类:

    1
    2
    3
    4
    5
    6
    7
    class OtherParent():
        def get_message(self):
            return"OtherParent"

    print(OtherChild.__mro__)
    Child().do_print()
    OtherChild().do_print()

    输出显示,Parent先于OtherParent来:

    1
    2
    3
    (<class '__main__.OtherChild'>, <class '__main__.Child'>, <class '__main__.Parent'>, <class '__main__.OtherParent'>, <class 'object'>)
    Parent
    Parent
  • ParentOtherParent的父类:

    1
    2
    3
    class OtherParent(Parent):
        def get_message(self):
            return"OtherParent"

    输出显示,OtherParent现在在Parent之前出现:

    1
    2
    3
    (<class '__main__.OtherChild'>, <class '__main__.Child'>, <class '__main__.OtherParent'>, <class '__main__.Parent'>, <class 'object'>)
    Parent
    OtherParent
  • 还有第二种情况,但现在其他孩子先从OtherParent继承,然后从Child继承:

    1
    2
    3
    4
    5
    6
    class OtherParent(Parent):
        def get_message(self):
            return"OtherParent"

    class OtherChild(OtherParent, Child):
        pass

    输出显示,OtherParentParent之前再次出现,但在Child之前也出现:

    1
    2
    3
    (<class '__main__.OtherChild'>, <class '__main__.OtherParent'>, <class '__main__.Child'>, <class '__main__.Parent'>, <class 'object'>)
    Parent
    Parent

  • 也许有人能解释最后一个不自然的案例。


    啊,我的朋友指出与YouTube上的例子有一点偏差:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Parent:
        def get_message(self):
            return"Parent"

    class Child(Parent):
        def do_print(self):
            print(super().get_message())

    class OtherParent(Parent): # <----- Inheritance of Parent makes it work
        def get_message(self):
            return"OtherParent"

    class OtherChild(Child, OtherParent):
        pass

    Child().do_print()
    OtherChild().do_print()