__mro__ 是类的方法解析顺序元组,由C3线性化算法在类定义时静态确定,可通过 ClassName.__mro__ 查看;它决定 super() 查找路径和同名方法覆盖顺序,不可修改。

Python 中 __mro__ 是什么,怎么看?
__mro__ 是一个元组,记录了类在查找方法或属性时的搜索顺序。它不是运行时动态计算的,而是在类定义完成时由 C3 线性化算法静态确定的。直接访问 ClassName.__mro__ 就能看到结果,比如:
class A: pass class B(A): pass class C(A): pass class D(B, C): passprint(D.mro)
main.D'>, main.B'>, main.C'>, main.A'>,
注意:这个顺序决定了 super() 调用时往哪走,也决定了同名方法最终被哪个类的版本覆盖。
立即学习“Python免费学习笔记(深入)”;
为什么 super() 有时跳过父类?
因为 super() 不是“调上一级父类”,而是按当前类的 __mro__ 中**下一个类**查找。如果某个类在 MRO 中排在更前,它的方法就会先被选中,哪怕它不是语法上的直接父类。
- 在多继承中,
super().__init__()的行为完全依赖于调用者的__mro__,而不是写这行代码的那个类本身 - 如果多个父类都实现了同一个方法(如
__init__),只有 MRO 中最靠前的那个会被执行——后面的不会自动链式调用,除非每个都显式写了super() - 漏写
super()是常见 bug:某个中间类没转发,会导致后续 MRO 中的类初始化逻辑被跳过
C3 线性化失败时会报什么错?
当继承结构无法满足 C3 算法约束(比如出现“钻石继承”但左右分支顺序冲突),Python 在类定义阶段就抛出 TypeError,错误信息明确指出冲突点:
功能列表:底层程序与前台页面分离的效果,对页面的修改无需改动任何程序代码。完善的标签系统,支持自定义标签,公用标签,快捷标签,动态标签,静态标签等等,支持标签内的vbs语法,原则上运用这些标签可以制作出任何想要的页面效果。兼容原来的栏目系统,可以很方便的插入一个栏目或者一个栏目组到页面的任何位置。底层模版解析程序具有非常高的效率,稳定性和容错性,即使模版中有错误的标签也不会影响页面的显示。所有的标
class A: pass class B(A): pass class C(A): pass class D(A, B): pass # ❌ TypeError: Cannot create a consistent method resolution order (MRO) for bases A, B
原因:B 已经继承 A,再让 D 同时继承 A 和 B,就破坏了 C3 要求的“局部优先”和“单调性”。解决办法是去掉冗余继承,比如改成 class D(B, C) 或 class D(B)。
自定义 __mro__ 可以吗?
不能。Python 禁止手动赋值或修改 __mro__,它是只读属性:
class X: pass X.__mro__ = (X, object) # ❌ AttributeError: readonly attribute
想干预方法解析顺序,只能调整继承声明顺序(如 class D(B, C) vs class D(C, B)),或使用 __getattribute__ / __getattr__ 做运行时拦截——但这绕过了 MRO,不属于“方法解析顺序”的范畴了。
MRO 的关键在于它是一次性、静态、不可变的;真正容易被忽略的是:即使你没显式用 super(),只要用了多重继承 + 同名方法,MRO 就已经在幕后决定谁的方法生效了。









