Python继承代码报错:TypeError参数不匹配问题排查
代码运行异常原因分析及修正
原问题代码及报错
Practice.py
import numpy as np class Parents_A: def __init__(self, *args): self.A_a = 0 self.A_b = np.array([]) if args: self.set(*args) @property def As(self): return self.A_a @property def bs0(self) -> float: return self.A_b[0] @property def bs1(self) -> float: return self.A_b[1] def set(self, A_a : float, A_b : np.ndarray): self.A_a = A_a self.A_b = A_b print('Setted!') class Parents_B: def __init__(self, B_a, B_b): self.B_a = B_a self.B_b = B_b class Child(Parents_B, Parents_A): def __init__(self, B_a, B_b, Parents_A): super().__init__(B_a, B_b, Parents_A) self.Iwant = Parents_A.As
main.py
import Practice import numpy as np if __name__ == '__main__': Data = Practice.Parents_A(1, ([0.9, 1.1])) calculator = Practice.Child(2, 3, Data)
报错信息
TypeError: __init__() takes 3 positional arguments but 4 were given
核心错误原因
1. Parent_A类的语法缩进错误
if args:语句位于__init__方法外部,此时args未定义,且无法访问实例self,逻辑上这部分代码应该放在__init__方法内部。- 所有
@property装饰的方法(As、bs0、bs1)以及set方法都没有缩进在Parents_A类的范围内,导致这些方法变成全局函数,无法访问类实例的属性,运行时会引发额外错误。
2. Child类初始化的参数传递错误
- 多重继承中,Python会按MRO方法解析顺序调用父类构造函数,
Child的继承顺序是Parents_B在前,因此super().__init__()会调用Parents_B.__init__,而该方法仅接受B_a和B_b两个参数(加上self共3个位置参数),但Child的__init__传入了3个额外参数(B_a、B_b、Parents_A实例),加上self总共4个参数,直接触发了报错。 Child.__init__的第三个参数命名为Parents_A,混淆了类名和实例,应该改为更清晰的名称(比如parent_a_inst),同时访问属性时应该用实例而非类名,即parent_a_inst.As而非Parents_A.As。
3. Parent_A实例化的参数类型问题
实例化Parents_A时传入的第二个参数是列表[0.9,1.1],但set方法要求传入np.ndarray类型,会导致类型不匹配错误。
修正后的代码示例
Practice.py
import numpy as np class Parents_A: def __init__(self, *args): self.A_a = 0 self.A_b = np.array([]) # 将if判断移到__init__内部 if args: self.set(*args) @property def As(self): return self.A_a @property def bs0(self) -> float: return self.A_b[0] if len(self.A_b) >=1 else 0.0 @property def bs1(self) -> float: return self.A_b[1] if len(self.A_b)>=2 else 0.0 def set(self, A_a : float, A_b : np.ndarray): self.A_a = A_a self.A_b = A_b print('Setted!') class Parents_B: def __init__(self, B_a, B_b): self.B_a = B_a self.B_b = B_b class Child(Parents_B, Parents_A): def __init__(self, B_a, B_b, parent_a_inst): # 分别调用两个父类的构造函数,避免super的MRO问题 Parents_B.__init__(self, B_a, B_b) # 如果需要初始化Parents_A,可按需调用 # Parents_A.__init__(self) self.Iwant = parent_a_inst.As
main.py
import Practice import numpy as np if __name__ == '__main__': # 传入正确的np.ndarray类型参数 Data = Practice.Parents_A(1, np.array([0.9, 1.1])) calculator = Practice.Child(2, 3, Data) print(calculator.Iwant) # 输出1
内容的提问来源于stack exchange,提问作者Pool_Noobbb
相关产品推荐
相关产品推荐

