Python中__init__()缺失必填位置参数问题排查与解决
Python多继承__init__参数错误分析与修复
问题重现
代码示例
class Base: def __init__(self, x, y, *args, **kwargs): pass class A(Base): def __init__(self, x, y, z, *args, **kwargs): super().__init__(x, y, *args, **kwargs) class B(Base): def __init__(self, x, y, t, *args, **kwargs): super().__init__(x, y, *args, **kwargs) class C(A, B): def __init__(self, x, y, z, t, *args, **kwargs): super().__init__(x, y, z, *args, **kwargs) C(1, 2, 3, 4)
错误回溯
Traceback (most recent call last): File "test.py", line 25, in <module> C(1, 2, 3, 4) File "test.py", line 22, in __init__ A.__init__(self, x, y, z, *args, **kwargs) File "test.py", line 10, in __init__ super().__init__(x, y, *args, **kwargs) TypeError: __init__() missing 1 required positional argument: 't'
添加*args和**kwargs后仍报错,需明确错误成因及修复方案。
错误成因
Python多继承遵循方法解析顺序(MRO),类C的MRO为 C → A → B → Base。当C调用super().__init__时,会先执行A的__init__方法;而A中的super()并非指向Base,而是MRO中A的下一个类——B。
此时A调用super().__init__(x, y, *args, **kwargs),实际是调用B的__init__方法,但B的__init__要求必须传入t参数,而A传递的参数中没有t(*args此时为空),因此触发TypeError。
修复方法
方法1:规范参数传递,适配MRO顺序
调整各个类的__init__,让每个类仅提取自身所需的特有参数,其余参数通过**kwargs传递给super(),确保后续父类能获取到所需参数:
class Base: def __init__(self, x, y, *args, **kwargs): self.x = x self.y = y class A(Base): def __init__(self, z, *args, **kwargs): super().__init__(*args, **kwargs) self.z = z class B(Base): def __init__(self, t, *args, **kwargs): super().__init__(*args, **kwargs) self.t = t class C(A, B): def __init__(self, x, y, z, t, *args, **kwargs): super().__init__(x=x, y=y, z=z, t=t, *args, **kwargs) C(1, 2, 3, 4)
方法2:显式调用所有父类的__init__
如果不想调整参数结构,可在C的__init__中直接调用A和B的__init__,传递各自所需参数。注意:这种方式会导致Base的__init__被执行两次,若Base中有初始化逻辑,需避免重复操作。
class Base: def __init__(self, x, y, *args, **kwargs): pass class A(Base): def __init__(self, x, y, z, *args, **kwargs): super().__init__(x, y, *args, **kwargs) class B(Base): def __init__(self, x, y, t, *args, **kwargs): super().__init__(x, y, *args, **kwargs) class C(A, B): def __init__(self, x, y, z, t, *args, **kwargs): A.__init__(self, x, y, z, *args, **kwargs) B.__init__(self, x, y, t, *args, **kwargs) C(1, 2, 3, 4)
内容的提问来源于stack exchange,提问作者Kevin Hsu
相关产品推荐
相关产品推荐

