Python多继承场景下类F的super()为何调用M类__init__方法?
核心原因:你对
super()的行为有常见误解 Python里的super()从来不是「硬绑定当前类的直接父类」,它的调用目标完全由**当前实例的方法解析顺序(MRO)**决定,和类定义时是不是独立写的没有关系。
先搞懂两个基础规则
- 所有Python类在创建时,都会通过C3线性化算法生成一张固定的方法解析顺序表,也就是MRO,你可以通过
类名.__mro__直接打印查看。对于你定义的C(F,M),它的MRO顺序是:C → F → M → object - 当你在某个类的方法里写
super()时,它会拿「当前运行时实例所属类」的MRO表,找到当前代码所在类在这张表里的位置,往后取顺位的下一个类,作为调用目标。
逐行对应执行流程
我们对着你的代码和输出一步步走:
- 执行
C()创建C类实例,自动进入C.__init__ C.__init__里第一行是super().__init__():查C的MRO,C后面第一个类是F,所以调用F.__init__,首先打印第一行输出:F constructor- 进入
F.__init__后第一次调用super().__init__():当前实例还是C的实例,MRO仍然是C→F→M→object,当前代码在F类里,所以找F在MRO里的下一位——也就是M,调用M.__init__,打印第二行:M constructor。M的__init__没有其他逻辑,执行完返回F类的代码流程。 - 接着F里第二次调用
super().__init__():逻辑和上一步完全一致,还是找MRO里F后面的M,再次调用M.__init__,打印第三行:M constructor,执行完返回F。 - F的
__init__全部执行完,回到C的__init__流程,执行最后一行打印,输出第四行:C constructor
补充澄清误区
你觉得F是独立类、和M没关系,是因为你只看了F的静态定义:如果单独实例化F,也就是直接跑F(),那F的MRO是F→object,这时候F里的super()确实会找object,不会触发M的逻辑。但当F被多继承的C放在M前面时,C的MRO会把M排在F后面,F里的super()自然就会调用到M的方法。
内容的提问来源于stack exchange,提问作者arin
相关产品推荐
相关产品推荐

