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

多类继承下如何让super().__init__()调用所有父类构造方法?

解决Python多继承中调用所有父类构造函数的问题

原代码中,类C继承自A和B,仅通过super().__init__()只能调用第一个父类A的构造函数,导致B的属性未被初始化。要在不硬编码父类名称的前提下调用所有父类的构造函数,有两种可行方案:

方案1:利用MRO链式调用(推荐)

这种方法要求所有父类的构造函数也通过super()调用,让Python的方法解析顺序(MRO)自动处理链式调用。即使后续新增父类,也无需修改C的代码。

修改后的代码:

import inspect

class A:
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.atr1 = 'Foo1'

class B:
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.atr2 = 'Foo2'
        
class C(A,B):
    def __init__(self) -> None:
        super().__init__()

# 验证代码
fooObj = C()
for i in inspect.getmembers(fooObj):
    if not i[0].startswith('_') and not inspect.ismethod(i[1]):
        print(i)

输出结果:

('atr1', 'Foo1')
('atr2', 'Foo2')

原理:C的MRO顺序是[C, A, B, object],调用super().__init__()时会按此顺序依次执行每个类的__init__方法,父类中super().__init__(*args, **kwargs)会继续调用MRO中的下一个类的构造函数。

方案2:遍历父类直接调用构造函数

如果无法修改父类的代码,可以在C的构造函数中遍历所有直接父类,逐个调用它们的构造函数。

修改后的代码:

import inspect

class A:
    def __init__(self):
        self.atr1 = 'Foo1'

class B:
    def __init__(self):
        self.atr2 = 'Foo2'
        
class C(A,B):
    def __init__(self) -> None:
        # 遍历所有直接父类并调用构造函数
        for base in self.__class__.__bases__:
            base.__init__(self)

# 验证代码
fooObj = C()
for i in inspect.getmembers(fooObj):
    if not i[0].startswith('_') and not inspect.ismethod(i[1]):
        print(i)

输出结果:

('atr1', 'Foo1')
('atr2', 'Foo2')

注意:此方法仅适用于直接父类无多层继承的场景,若父类本身还有父类,可能会导致重复调用或遗漏,因此方案1更通用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:20:14