Python中MRO与super()不符合预期:Bottom2调用method()缺失Top输出原因
Python多继承中super调用未执行的问题分析
问题背景
在Python 3.10.7环境下定义了如下类结构:
Top类的method方法输出'Top'Left、Right类继承自Top,它们的method方法输出自身名称后调用super().method()Bottom和Bottom2类继承自Left和Right
调用Bottom2().method()时,预期输出'Bottom2'和'Top',但实际仅输出'Bottom2',具体代码及执行结果如下:
import platform print(platform.python_version()) # 输出 '3.10.7' class Top: def method(self): print('Top') class Left(Top): def method(self): print('Left') super().method() class Right(Top): def method(self): print('Right') super().method() class Bottom(Left, Right): def method(self): print('Bottom') super(Left, self).method() class Bottom2(Left, Right): def method(self): print('Bottom2') super(Right, self).method # 问题所在行 # 执行结果 Bottom().method() # 输出: # Bottom # Right # Top print(Bottom.mro()) # 输出:[<class '__main__.Bottom'>, <class '__main__.Left'>, <class '__main__.Right'>, <class '__main__.Top'>, <class 'object'>] Bottom2().method() # 仅输出:Bottom2 print(Bottom2.mro()) # 输出:[<class '__main__.Bottom2'>, <class '__main__.Left'>, <class '__main__.Right'>, <class '__main__.Top'>, <class 'object'>]
原因解析
1. 核心问题:未执行方法调用
Bottom2的method方法中,super(Right, self).method只是引用了方法对象,没有添加括号()触发执行,所以这一行不会产生任何输出。
2. 补充:super的工作逻辑
即使补上括号,也要明确super(cls, self)的作用:它会在当前类的MRO(方法解析顺序)列表中,找到cls的下一个类,再调用对应方法。
从Bottom2的MRO列表[Bottom2, Left, Right, Top, object]来看:super(Right, self)会指向MRO中Right之后的Top类,因此super(Right, self).method()会直接调用Top.method(),输出'Top',符合预期。
修复方案
给方法引用加上括号,修改后的Bottom2类如下:
class Bottom2(Left, Right): def method(self): print('Bottom2') super(Right, self).method() # 补上括号执行方法
此时调用Bottom2().method()会输出:
Bottom2 Top
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

