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

Call resolution order in Python with multiple inheritance

我正在观看 Youtube 的 Python 演讲,发现了一个有趣的语言功能。但是,当我尝试 运行 测试代码时,它不起作用,我想了解原因。

我期待它打印这个:

Parent
OtherParent

但我却得到了这个:

Parent
Parent

示例代码:

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 位)

啊,我的朋友指出了与 Youtube 上示例的一个小偏差:

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()

问题的评论中提到了正确的解释,即来自 OtherChild class 的 MRO(link 发表在评论中:How does the order of mixins affect the derived class?)。

查看 OtherChild class 的 MRO 的不同输出取决于不同的继承:

  1. OtherParent没有parentclass:

    class OtherParent():
        def get_message(self):
            return "OtherParent"
    
    print(OtherChild.__mro__)
    Child().do_print()
    OtherChild().do_print()
    

    输出显示 ParentOtherParent 之前:

    (<class '__main__.OtherChild'>, <class '__main__.Child'>, <class '__main__.Parent'>, <class '__main__.OtherParent'>, <class 'object'>)
    Parent
    Parent
    
  2. ParentOtherParent 的 parent class:

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

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

    (<class '__main__.OtherChild'>, <class '__main__.Child'>, <class '__main__.OtherParent'>, <class '__main__.Parent'>, <class 'object'>)
    Parent
    OtherParent
    
  3. 仍然是情况 2,但现在 OtherChild 首先继承自 OtherParent,然后是 Child:

    class OtherParent(Parent):
        def get_message(self):
            return "OtherParent"
    
    class OtherChild(OtherParent, Child):
        pass
    

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

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

也许有人可以解释最后一个乍一看不自然的情况。