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

Python多继承机制疑问:为何不同继承场景下super()表现不同?

Python多继承中super()的执行逻辑疑问

代码示例

class base:
    def __init__(self):
        print('base')


class F0(base):
    def __init__(self):
        super().__init__()
        print("F0")


class F1(F0):
    def __init__(self):
        super().__init__()
        print("F1")


class F2(F0):
    def __init__(self):
        super().__init__()
        print("F2")


class F3(F1, F2):
    def __init__(self):
        super().__init__()
        print("F3")

# -------------------------------------
class Base_1():
    def __init__(self):
        print('base_1')

class Base_2():
    def __init__(self):
        print('base_2')
        
class Base_3(Base_1, Base_2):
    def __init__(self):
        super().__init__()
        print("base_3")


if __name__ == '__main__':
    f3 = F3()
    print(F3.mro())

    base_3 = Base_3()
    print(Base_3.mro())

运行输出

base
F0
F2
F1
F3
[<class '__main__.F3'>, <class '__main__.F1'>, <class '__main__.F2'>, <class '__main__.F0'>, <class '__main__.base'>, <class 'object'>]
base_1
base_3
[<class '__main__.Base_3'>, <class '__main__.Base_1'>, <class '__main__.Base_2'>, <class 'object'>]

已理解内容

  • 对于Base_3类,它继承自Base_1和Base_2。在Base_3的__init__方法中调用super().__init__()时,仅会执行Base_1的__init__方法。

疑问

F1和F2拥有共同父类F0(F0继承自base),而F3继承自F1和F2。为何在F3的__init__方法中调用super().__init__()时,会同时执行F1和F2的__init__方法?


解答

核心原因在于**Python的方法解析顺序(MRO)**以及每个类中super()的调用行为:

  1. MRO的作用:Python会为每个类生成一个方法解析顺序列表(可通过mro()方法查看),这个列表决定了调用继承方法时的查找顺序。

    • F3的MRO:F3 → F1 → F2 → F0 → base → object
    • Base_3的MRO:Base_3 → Base_1 → Base_2 → object
  2. super()的工作逻辑:super()并不直接指向父类,而是根据当前类在MRO中的位置,返回MRO中下一个类的实例。关键在于,只有当前类的方法中调用了super(),才会继续触发MRO中下一个类的对应方法。

F3的执行流程:

  • 调用F3.__init__(),其中的super()指向MRO中的下一个类F1,执行F1.__init__()
  • F1.__init__()中的super()指向MRO中的下一个类F2(MRO已处理菱形继承,避免重复执行F0),执行F2.__init__()
  • F2.__init__()中的super()指向MRO中的下一个类F0,执行F0.__init__()
  • F0.__init__()中的super()指向base,执行base.__init__()
  • 之后依次回溯打印F0、F2、F1、F3

Base_3的执行流程:

  • 调用Base_3.__init__(),super()指向Base_1,执行Base_1.__init__()
  • 但Base_1.__init__()中没有调用super(),MRO的后续链条被中断,Base_2.__init__()不会被执行,直接回溯打印base_3

简单来说,F系列的每个类都在__init__里调用了super(),所以会顺着MRO完整走一遍;而Base_1的__init__没有调用super(),导致链条断裂,Base_2的方法不会被触发。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:00:58