Python类继承顺序教程_MRO机制与多继承解析

MRO是Python多继承中方法解析的线性顺序,由C3算法确定,存储在__mro__属性中,确保子类优先、父类按声明序排列且无重复。

Python 的类继承顺序由 MRO(Method Resolution Order,方法解析顺序)决定,它决定了多继承时属性和方法从哪个父类开始查找。理解 MRO 是正确使用多继承、避免意外覆盖或 AttributeError 的关键。

什么是 MRO?

MRO 是一个类的线性化继承链,以元组形式存储在类的 __mro__ 属性中,或通过 mro() 方法获取。Python 使用 C3 线性化算法计算 MRO,确保: - 子类总在父类之前 - 各父类按声明顺序出现 - 每个类只出现一次,且满足所有父类的局部优先级约束

查看与验证 MRO

直接访问类的 __mro__ 或调用 mro()

class A: pass
class B: pass
class C(A, B): pass
print(C.__mro__) # ain__.C'>, , ,

注意:MRO 在类定义完成时即确定,不能运行时修改;若继承关系导致无法满足 C3 规则(如 class D(B, A)C(A, B) 共存于某继承结构中),Python 会在定义时抛出 TypeError: Cannot create a consistent method resolution order (MRO)

立即学习“Python免费学习笔记(深入)”;

多继承中的方法查找逻辑

当调用 obj.method() 时,Python 按 MRO 顺序从左到右搜索第一个匹配的方法:

  • 不会跳过中间类——即使某个父类没定义该方法,也会继续查下一个
  • super() 默认按当前类的 MRO 继续向后查找,不是简单调父类
  • 重写方法时,若需调用“下一个”类的同名方法,应统一用 super(),而非硬编码父类名,否则易破坏 MRO 链

例如:
class A:
  def hello(self): print("A")
class B:
  def hello(self): print("B")
class C(A, B):
  def hello(self):
    super().hello() # 实际调 A.hello,因 A 在 MRO 中先于 B

常见陷阱与建议

  • 避免“钻石继承”中手动指定父类调用(如 A.__init__(self)),容易遗漏或重复初始化
  • 设计 mixin 类时,把通用行为放在靠右的父类位置,让具体类优先控制流程
  • 使用 isinstance(obj, cls)issubclass(sub, cls) 时,它们也遵循 MRO 判定继承关系
  • 调试复杂继承时,打印 cls.__mro__ 是最快定位问题的方式