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()的调用行为:
MRO的作用:Python会为每个类生成一个方法解析顺序列表(可通过
mro()方法查看),这个列表决定了调用继承方法时的查找顺序。F3的MRO:F3 → F1 → F2 → F0 → base → objectBase_3的MRO:Base_3 → Base_1 → Base_2 → object
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
相关产品推荐
相关产品推荐

