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

Python多继承触发TypeError:关键字参数重复赋值问题排查

菱形继承中__init__参数冲突的原因与解决方法

问题原因

你遇到的错误本质是重复传递同名参数导致的:

  • 菱形继承结构里,B和C都继承自D,当A实例化时,MRO顺序是A → B → C → D → object
  • 如果B和C的__init__方法都显式向D传递d参数(哪怕用了super()),当执行到C的super()调用D时,d参数已经被B传递过一次,就会触发got multiple values for keyword argument 'd'错误
  • 你提到用super()消除了错误但传不了参数,大概率是没通过**kwargs把未处理的参数传递给后续父类,导致参数在传递链中丢失

解决方法:统一用**kwargs传递参数

核心思路是让每个类只处理自己专属的参数,剩余参数通过**kwargs传递给MRO链中的下一个类,确保D的__init__只被调用一次且只接收一次d参数。

正确代码示例

from abc import ABC, abstractmethod

# 顶层抽象基类D
class D(ABC):
    def __init__(self, d, **kwargs):
        super().__init__(**kwargs)  # 兼容更高层父类,无则无害
        self.d = d

# 中间类B,仅处理自身参数b
class B(D):
    def __init__(self, b, **kwargs):
        super().__init__(**kwargs)
        self.b = b

# 中间类C,仅处理自身参数c
class C(D):
    def __init__(self, c, **kwargs):
        super().__init__(**kwargs)
        self.c = c

# 子类A,处理自身参数a,其余参数传递给父类
class A(B, C):
    def __init__(self, a, **kwargs):
        super().__init__(**kwargs)
        self.a = a

# 实例化测试
a_obj = A(a=1, b=2, c=3, d=4)
print(a_obj.d, a_obj.b, a_obj.c, a_obj.a)  # 输出:4 2 3 1

关键细节说明

  1. 所有类的__init__都保留**kwargs参数,用于接收并传递未处理的参数
  2. 每个类只提取自己需要的参数(比如B取b,C取c),剩余参数通过super().__init__(**kwargs)传递
  3. D作为顶层抽象基类,提取自己需要的d参数后,仍保留super().__init__(**kwargs),确保兼容Python的object类(即使没有更高层父类,这步也不会报错)

错误写法示例(对比)

如果你的代码是类似下面的写法,就会触发参数冲突:

# 错误写法:B和C都显式传递d给D
class B(D):
    def __init__(self, b, d):
        super().__init__(d=d)  # 显式传d
        self.b = b

class C(D):
    def __init__(self, c, d):
        super().__init__(d=d)  # 再次传d
        self.c = c

class A(B, C):
    def __init__(self, a, b, c, d):
        super().__init__(b=b, c=c, d=d)  # 执行时B先调用super到C,C又传d给D,导致重复

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 20:33:26