You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python继承MRO机制疑问:为何不同多继承场景执行结果不同?

Python 多继承MRO中分支执行差异的原因

先明确两个场景的继承结构和MRO计算结果,再拆解执行逻辑:

场景1:共同父类分支的执行逻辑

继承链:Parent(Middle1, Middle2),Middle1(Origin1),Middle2(Origin1)

用C3线性化算法计算的Parent的MRO列表是:
[Parent, Middle1, Middle2, Origin1, object]

结合你描述的执行顺序(Origin1→Middle2→Middle1→Parent),推测每个类的hello()实现是先调用super().hello(),再打印自身标识,示例代码如下:

class Origin1:
    def hello(self):
        super().hello()  # 指向MRO中Origin1的下一个类object,无hello方法
        print("Origin1.hello")

class Middle1(Origin1):
    def hello(self):
        super().hello()  # 指向MRO中Middle1的下一个类Middle2
        print("Middle1.hello")

class Middle2(Origin1):
    def hello(self):
        super().hello()  # 指向MRO中Middle2的下一个类Origin1
        print("Middle2.hello")

class Parent(Middle1, Middle2):
    def hello(self):
        super().hello()  # 指向MRO中Parent的下一个类Middle1
        print("Parent.hello")

调用Parent().hello()的执行链严格遵循MRO顺序:Parent→Middle1→Middle2→Origin1,每个super()都会触发下一个类的hello(),所以所有类的方法都被执行。

场景2:独立分支被忽略的核心原因

当Middle2改为继承Origin2后,继承链变为:Parent(Middle1, Middle2),Middle1(Origin1),Middle2(Origin2)

此时Parent的MRO列表更新为:
[Parent, Middle1, Origin1, Middle2, Origin2, object]

你观察到Middle2和Origin2的hello()被忽略,本质是执行链在Origin1处中断:

  • Middle1的hello()通过super()调用Origin1的hello()
  • 如果Origin1的hello()没有调用super().hello()(或调用后因object无对应方法终止),那么MRO中Origin1之后的Middle2、Origin2就不会被触发,自然不会执行它们的hello()

关键结论

Python的super()不是简单调用“父类方法”,而是基于当前实例的MRO列表,找到当前类之后的第一个类的同名方法。只有当每个类的目标方法都主动调用super()时,才会沿着MRO完整遍历所有分支。场景2的差异完全由MRO顺序变化+执行链中断导致。

内容的提问来源于stack exchange,提问作者IAmVerySmart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:05:44