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

Python中MRO机制疑问:多继承下super调用异常及解决方案

Python继承中super调用问题解析与解决

问题原因

你遇到的核心问题是Python的**方法解析顺序(MRO)**在起作用。当你创建C类的实例时,self是C的对象,它的MRO顺序是:C → A → B → Base → object。

在A的__init__里使用super(A, self)时,super会从MRO中A的下一个类开始查找方法,也就是B,而非你以为的Base。这就导致调用了B的__init__,但B的__init__只接受1个参数,你传了2个,自然报错。

另外你代码里还有个小问题:C的__init__中第二次调用A.__init__(self, attr2)时,A的__init__需要3个参数(self、attr、attr_base1、attr_base2),这里只传了2个,也会引发参数不匹配错误。

解决方案

方案1:直接显式调用Base的__init__

如果你明确要让A的初始化直接调用Base的方法,绕过MRO的链式查找,直接写Base.__init__(self, attr_base1, attr_base2)即可:

class Base(object):
    def __init__(self, attr_base1, attr_base2):
        self.attr_base1 = attr_base1
        self.attr_base2 = attr_base2

    def foo(self):
        print ('A.foo()')

class A(Base):
    def __init__(self, attr, attr_base1, attr_base2):
        # 直接调用Base的初始化方法,跳过MRO
        Base.__init__(self, attr_base1, attr_base2)
        self.attr1 = attr

class B(Base):
    def __init__(self, attr):
        self.attr2 = attr

    def foo(self):
        print ('B.foo()')

class C(A, B):
    def __init__(self, attr1, attr2):
        # 修复第二次调用的参数问题
        A.__init__(self, attr1, "b1", "b2")
        # 如果要初始化B的属性,直接调用B的__init__
        B.__init__(self, attr2)

c = C(1, 2)
print(c.attr1, c.attr_base1, c.attr_base2, c.attr2)  # 输出 1 b1 b2 2

方案2:调整类的初始化方法适配MRO

如果想保留super的链式调用,需要让所有相关类的__init__都兼容MRO链,比如给B的__init__添加super调用,并处理可变参数:

class Base(object):
    def __init__(self, attr_base1, attr_base2):
        self.attr_base1 = attr_base1
        self.attr_base2 = attr_base2

    def foo(self):
        print ('A.foo()')

class A(Base):
    def __init__(self, attr, attr_base1, attr_base2, *args, **kwargs):
        super().__init__(attr_base1, attr_base2)
        self.attr1 = attr

class B(Base):
    def __init__(self, attr, *args, **kwargs):
        self.attr2 = attr
        # 调用MRO下一个类的初始化,这里会到Base
        super().__init__(*args, **kwargs)

class C(A, B):
    def __init__(self, attr1, attr2):
        # 按MRO顺序初始化,C→A→B→Base
        super().__init__(attr1, "b1", "b2", attr2)

c = C(1, 2)
print(c.attr1, c.attr_base1, c.attr_base2, c.attr2)  # 输出 1 b1 b2 2

这种方式更符合Python的继承设计,但需要所有父类的初始化方法都配合链式调用。

内容的提问来源于stack exchange,提问作者Mr.O

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 16:47:31