构造一个菱形继承结构,验证MRO的计算顺序,交换父类声明顺序看MRO怎么变,再验证一个无法线性化的继承关系会被Python直接拒绝。
B和C都继承自A,D同时继承B和C——想知道d.who()该调用谁的方法。
代码class A: def who(self): return "A" class B(A): def who(self): return "B" class C(A): def who(self): return "C" class D(B, C): pass
D自己没定义who,按MRO顺序找第一个有who的类。
结果D.__mro__ 是: ['D', 'B', 'C', 'A', 'object'] d.who() 调用的是: 'B'
D的方法解析顺序是"D自己→B→C→A→object"——不是简单的"先左边全部深度优先"(那样会是D→B→A→C→A,A重复出现),C3线性化保证了:每个类只出现一次,而且子类永远排在父类前面,多个父类之间保持它们在class语句里声明的顺序(B在C前面)。
只是把B(C,B)里的顺序换一下。
代码与结果class E(C, B): pass E.__mro__ 是: ['E', 'C', 'B', 'A', 'object']
验证了class语句里父类的书写顺序是有意义的——D(B, C) 和 E(C, B) 除了父类声明顺序互换,结构完全一样,但MRO完全翻转了B和C的相对位置,导致找同名方法时优先级也反过来了。
故意构造一个C3算法无法给出一致顺序的继承关系。
代码与结果class X: pass class Y: pass class M1(X, Y): pass class M2(Y, X): pass -- 故意反过来声明 class Bad(M1, M2): -- 会失败 pass 报错: TypeError: Cannot create a consistent method resolution order (MRO) for bases X, Y
class Bad(M1, M2) 这一行就抛出TypeError,而不是给出一个"凑合能用但语义混乱"的顺序。这也是多继承设计里一个的护栏:继承关系本身自相矛盾时,Python不会悄悄给你一个不确定的行为,而是在类定义阶段就报错拦下来。
每一步都是本文上面用Python 3.14跑出来的原始结果。
__mro__:查看C3线性化算出的方法解析顺序