mro是python用c3线性化算法计算出的类继承顺序列表,决定属性查找路径;super()依mro查找“下一个类”而非父类,要求所有同名方法统一使用super()以保障协作式多重继承。

super 不是简单地调用父类方法,而是根据 MRO(Method Resolution Order,方法解析顺序) 查找下一个类中定义的方法。它返回一个代理对象,用于在 MRO 链上“向后”查找并调用合适的方法,从而支持协作式多重继承。
MRO 是什么?
MRO 是 Python 为每个类动态计算出的一个线性化继承顺序列表,决定了属性和方法的查找路径。Python 使用 C3 线性化算法生成 MRO,保证: - 子类总在父类之前 - 各父类按声明顺序出现 - 满足单调性(不破坏原有继承关系)
可通过 ClassName.__mro__ 或 ClassName.mro() 查看。例如:
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
print(D.__mro__)
# → (
super() 的查找逻辑
super() 实际接收两个参数:super(cls, instance_or_type)。常用形式如 super().__init__() 是简写,等价于 super(CurrentClass, self).__init__()。它的查找行为是:
立即学习“Python免费学习笔记(深入)”;
- 从
self所属实例的类的 MRO 中,找到CurrentClass的位置 - 取该位置之后的**第一个类**,在其内部查找目标方法(如
__init__) - 若没找到,则继续向后查找,直到找到或报
AttributeError
关键点:super 不找“父类”,而找 MRO 中“下一个类”。在多重继承中,这个“下一个”可能是兄弟类、远亲类,甚至 object。
为什么必须所有方法都用 super?
协作式继承要求所有参与类的同名方法(尤其是 __init__、__new__)都使用 super(),否则 MRO 链会中断:
- 如果某个类用
A.__init__(self)硬编码调用,就跳过了 MRO 后续类,后续的super()将无法继续传递 - 只有全部统一用
super(),才能让每个类只负责自己那部分初始化,再把控制权交还给 MRO 下一环 - 典型反例:混用
Parent.__init__(self)和super().__init__()会导致某些类的__init__被跳过
常见误区与调试技巧
容易误以为 super 总是调父类,或认为 “super() == 父类”。实际应以 MRO 为准:
- 打印
self.__class__.__mro__可直观看到当前实例的完整查找链 - 在方法中加
print(self.__class__.__name__),观察每次 super 调用时实际执行的是哪个类的方法 - 注意类方法中
super()的第二个参数:静态方法/类方法需显式传入类或类型,如super(Cls, cls).method()
不复杂但容易忽略细节。理解 MRO + super 的配合机制,是写出健壮多重继承代码的基础。










