Python多层继承(父类与祖父类)下替代构造函数调用报错问题
错误原因
- 调用
Foo3.from_list()时,类方法的cls参数为Foo3,调用父类from_list方法时cls会透传过去 - 父类
Foo1的from_list方法内执行return cls(2)等价于Foo3(2),但Foo3的__init__只接受self一个位置参数,因此抛出参数不匹配错误 - 额外写法问题:
super(Foo2, Foo3)的写法不符合常规逻辑,你要获取Foo3的父类实现,直接写super()即可,不需要显式传入Foo2
修复方案
方案1:保留Foo3无参构造的设计,调整from_list逻辑
如果你需要严格保持Foo3实例化不需要传参,直接修改Foo3.from_list的实现即可:
class Foo1: def __init__(self, x): print("I am Foo1") @classmethod def from_list(cls, some_list): # 原代码未使用some_list,这里补充实际逻辑:取列表第一个元素作为构造参数 x = some_list[0] return cls(x) class Foo2(Foo1): pass class Foo3(Foo2): def __init__(self): super().__init__(5) @classmethod def from_list(cls): # 直接构造Foo3实例即可,不需要调用父类的构造逻辑 return cls() # 测试代码 foo1_using_init = Foo1(2) foo1_using_from_list = Foo1.from_list([5, 6, 7]) foo3_using_init = Foo3() foo3_using_from_list = Foo3.from_list() # 运行正常
方案2:保留调用父类from_list的逻辑,兼容参数传递
如果你需要复用父类from_list的全部处理逻辑,只需给Foo3的__init__加可选参数即可:
class Foo3(Foo2): # 添加可选参数x,传入的参数会被忽略,固定用5调用父类构造 def __init__(self, x=None): super().__init__(5) @classmethod def from_list(cls): # 正确的super写法,调用父类的from_list方法 return super().from_list(some_list=[1, 2, 3])
修改后父类from_list传入的构造参数会被Foo3.__init__接收并忽略,不会触发参数错误。
内容的提问来源于stack exchange,提问作者Vader
相关产品推荐
相关产品推荐

