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

单祖父、双父类、子类的多继承TypeError问题排查

菱形多继承中的初始化参数错误分析与解决

问题重现

采用菱形多继承结构:Weapon作为基类,Edge和Long继承自Weapon,Zweihander同时继承Long和Edge。当Edge继承Weapon后,创建Zweihander对象会抛出错误:

TypeError: Edge.__init__() missing 1 required positional argument: 'sharpness'

错误指向Long类构造函数的super().__init__()语句;单独创建Edge的子类(如Knife)时,程序同样会崩溃。

核心原因:MRO(方法解析顺序)的影响

Python多继承遵循方法解析顺序(MRO),Zweihander的MRO顺序为:
Zweihander → Long → Edge → Weapon → object

当调用Long.__init__(self, length)时,Long内部的super().__init__()不会直接调用Weapon的__init__,而是按照MRO顺序找到下一个类——Edge的__init__。但Edge的__init__需要传入sharpness参数,Long的__init__调用super()时并未传递该参数,因此触发错误。

解决方法

方法1:统一使用super()+关键字参数(推荐)

这种方式符合Python多继承设计规范,自动遵循MRO顺序处理初始化:

class Weapon:
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.does_damage = "very yes"

    def attack(self):
        print("Je touche!")


class Edge(Weapon):
    def __init__(self, sharpness, **kwargs):
        super().__init__(**kwargs)
        self.sharpness = sharpness


class Long(Weapon):
    def __init__(self, length, **kwargs):
        super().__init__(**kwargs)
        self.length = length


class Zweihander(Long, Edge):
    def __init__(self, name, length, sharpness):
        super().__init__(length=length, sharpness=sharpness)
        self.name = name

    def warning(self):
        print("I will show you...\nTHE GREATEST NIGHTMARE!!!")


# 测试Zweihander
soulcal = Zweihander(name="soulcal", sharpness=100, length=54)
soulcal.warning()

# 测试单独的Edge子类
class Knife(Edge):
    def __init__(self, name, sharpness):
        super().__init__(sharpness=sharpness)
        self.name = name

knife = Knife(name="pocket knife", sharpness=80)
print(knife.sharpness)
print(knife.does_damage)

方法2:直接调用基类__init__(不推荐,易维护性差)

如果坚持直接调用父类初始化,需跳过super()的MRO查找,直接调用Weapon的__init__:

class Weapon:
    def __init__(self):
        self.does_damage = "very yes"

    def attack(self):
        print("Je touche!")


class Edge(Weapon):
    def __init__(self, sharpness):
        Weapon.__init__(self)
        self.sharpness = sharpness


class Long(Weapon):
    def __init__(self, length):
        Weapon.__init__(self)
        self.length = length


class Zweihander(Long, Edge):
    def __init__(self, name, length, sharpness):
        Long.__init__(self, length)
        Edge.__init__(self, sharpness)
        self.name = name

    def warning(self):
        print("I will show you...\nTHE GREATEST NIGHTMARE!!!")


soulcal = Zweihander(name="soulcal", sharpness=100, length=54)
soulcal.warning()

knife = Edge(sharpness=80)
print(knife.sharpness)

这种方式破坏了super()的MRO机制,后续继承结构变更时容易引发新问题,仅适用于简单继承场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:31:37