Python MRO机制疑问:多继承下方法调用顺序解析
Python多继承中super()调用顺序不符合预期问题解析
问题代码
class A: def gg(self): print ('Class A') class B(A): def gg(self): print('First Class B') super().gg() print('Class B') class C(A): def gg(self): print('First Class C') super().gg() print('Class C') class D (B,C): def gg(self): print('First Class D') super().gg() print('Class D') good = D() good.gg()
预期输出
- "First Class D"(函数首行输出)
- "First Class B"(调用super()进入首个父类B的方法首行)
- "Class A"(B中super()调用父类A的方法)
- "Class B"(B中方法的最后一行输出)
- "First Class C"(进入第二个父类C的方法首行)
- "Class A"(C中super()调用父类A的方法)
- "Class C"(C中方法的最后一行输出)
- "Class D"(D中方法的最后一行输出)
实际输出
First Class D First Class B First Class C Class A Class C Class B Class D
疑问点
- 为何从"First Class B"直接跳到"First Class C",不经过"Class A"和"Class B"?
- 为何"Class A"之后是"Class C"而非"Class B"?
问题原因与解析
你的核心错误是误解了super()的工作逻辑:它不是直接调用当前类的父类方法,而是按照类的MRO(方法解析顺序),找到当前类在MRO列表中的下一个类,调用其同名方法。
1. 先明确D类的MRO顺序
Python中可以通过print(D.__mro__)查看类的方法解析顺序,你的代码中D的MRO是:
D → B → C → A → object
2. 逐行拆解gg()的执行流程
- 调用
good.gg(),先打印First Class D,然后执行super().gg()——这里的super()指向MRO中D的下一个类B,进入B的gg()方法。 - 执行B的gg(),先打印
First Class B,然后执行super().gg()——注意,这里的super()不是指向B的父类A,而是按MRO顺序,B的下一个类是C,所以调用C的gg()方法。 - 执行C的gg(),先打印
First Class C,然后执行super().gg()——MRO中C的下一个类是A,调用A的gg()方法。 - 执行A的gg(),打印
Class A,没有后续super()调用,方法执行完毕,回到C的gg()。 - C的gg()继续执行剩余代码,打印
Class C,方法结束,回到B的gg()。 - B的gg()继续执行剩余代码,打印
Class B,方法结束,回到D的gg()。 - D的gg()继续执行剩余代码,打印
Class D,整个流程结束。
3. 你的预期错误点总结
- 错误认为B中的super()直接调用父类A的方法,但实际上Python多继承按MRO线性链处理,B的下一个类是C而非A。
- 错误认为父类B的方法会完整执行完毕后才轮到C,但实际上super()是沿着MRO链“深入”调用,直到链的末端(A)才会回溯执行每个方法的剩余代码。
- 错误认为A的gg()会被调用两次,但MRO列表中每个类只会出现一次,因此A的方法仅执行一次。
内容的提问来源于stack exchange,提问作者coke979
相关产品推荐
相关产品推荐

