class Base(object):
def __init__(self):
print("enter Base")
print("leave Base")
class A(Base):
def __init__(self):
print("enter A")
super().__init__()
print("leave A")
class B(Base):
def __init__(self):
print("enter B")
super().__init__()
print("leave B")
class C(A, B):
def __init__(self):
print("enter C")
super().__init__()
print("leave C")
c = C()
enter C
enter A
enter B
enter Base
leave Base
leave B
leave A
leave C
1. 先查看 C 的 MRO 继承链
print(C.__mro__)
# 输出:(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>)
super() 的逻辑:不是固定找直接父类,而是沿着 MRO 列表找下一个类。
2. 逐行拆解执行流程
c = C()→ 执行C.__init__- 打印
enter C super().__init__():MRO 中 C 的下一个是 A → 进入A.__init__
- 打印
- 执行
A.__init__- 打印
enter A super().__init__():MRO 中 A 的下一个是 B → 进入B.__init__
- 打印
- 执行
B.__init__- 打印
enter B super().__init__():MRO 中 B 的下一个是 Base → 进入Base.__init__
- 打印
- 执行
Base.__init__- 打印
enter Base - 打印
leave BaseBase 没有 super,本层构造函数结束,逐层回退
- 打印
- 回到 B 剩余代码:打印
leave B - 回到 A 剩余代码:打印
leave A - 回到 C 剩余代码:打印
leave C
三、关键易错点区分
- 如果不用
super(),手动写Base.__init__(self): A 和 B 都会单独调用 Base,Base 会被执行两次; super()依靠 MRO 保证公共父类 Base 只初始化一次(钻石继承问题解决方案);- 打印规律:先从上到下「enter」进入各个子类,再从最底层父类往回逐层打印「leave」。
疑问 1:为什么 A 没有直接进入 Base?
因为多继承 MRO 重排了继承顺序:
C(A,B) 的 MRO 是 C,A,B,Base,
在 A 中写 super(),解释器去 MRO 找 A 的下一位,是 B,不是 Base。
A 根本不会直接调用 Base,而是交给 B 去执行。
疑问 2:为什么 B 执行完 Base,A 就跟着结束了?
A 内部逻辑只有三行:
print("enter A")
super().__init__() # 整段B+Base的逻辑全部在这里跑完
print("leave A")
super().__init__() 是阻塞调用,必须等它里面所有嵌套代码(B、Base 全部执行完、全部 return),才会执行下一行 print("leave A")。
流程等价嵌套函数调用:
C{
enter C
A{
enter A
B{
enter B
Base{
enter Base
leave Base
}
leave B
}
leave A
}
leave C
}
对比:如果不用 super,手动写父类会怎么样?
假如 A 里不写 super,直接硬编码 Base.__init__(self):
class A(Base):
def __init__(self):
print("enter A")
Base.__init__(self)
print("leave A")
此时 A 会直接调用 Base,B 也会再调用一次 Base,Base 执行两遍,这就是钻石继承的重复初始化坑,super()+MRO 就是为了解决这个问题。




