You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多继承下调用双父类run方法仅执行首个父类实现是Bug吗?

结论

该现象不属于Python的Bug,是Python类方法查找机制的正常表现。

原因分析

你调用CarChild1.run(self)和CarChild2.run(self)时传入的self始终是CarChild3的实例,而run方法内部调用self._print_name时,Python会按照CarChild3的方法解析顺序(MRO)查找对应方法。
由于CarChild3的继承顺序为(CarChild1, CarChild2),且自身没有实现_print_name方法,MRO中排在前面的CarChild1的_print_name会被优先匹配,因此两次调用最终都执行了CarChild1的打印逻辑,才会输出两次CarChild1。

解决方案

以下三种方案都可以实现你预期的输出效果:

方案1:父类run方法显式绑定自身的打印方法

无需修改子类,直接调整父类run方法的实现,固定调用当前类的打印逻辑,不通过self动态查找:

class CarChild1:
    def run(self):
        CarChild1._print_name(self)
    def _print_name(self):
        print('CarChild1')

class CarChild2:
    def run(self):
        CarChild2._print_name(self)
    def _print_name(self):
        print('CarChild2')

class CarChild3(CarChild1, CarChild2):
    def run(self):
        CarChild1.run(self)
        CarChild2.run(self)

方案2:子类直接调用两个父类的打印方法

如果父类代码不可修改,可以直接调整子类run方法,跳过父类run的动态查找逻辑:

class CarChild3(CarChild1, CarChild2):
    def run(self):
        CarChild1._print_name(self)
        CarChild2._print_name(self)

方案3:使用双下划线私有方法避免覆盖

Python中双下划线开头的方法会被自动做名称修饰,不会被子类的同名方法覆盖,是官方推荐的类私有方法实现方式:

class CarChild1:
    def run(self):
        self.__print_name()
    def __print_name(self):
        print('CarChild1')

class CarChild2:
    def run(self):
        self.__print_name()
    def __print_name(self):
        print('CarChild2')

class CarChild3(CarChild1, CarChild2):
    def run(self):
        CarChild1.run(self)
        CarChild2.run(self)

三种方案运行后都会输出预期结果:

CarChild1
CarChild2

内容的提问来源于stack exchange,提问作者InfoLearner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 21:39:01