Python多继承场景下super().__init__()传参失败原因及正确实现方案
问题原因
Python的super()不会直接遍历调用所有父类的同名方法,而是按照方法解析顺序(MRO) 依次调用继承链上的下一个方法:
- Test类的MRO顺序为
Test -> School -> Exam -> object,原有代码中super().__init__(school_name, exam_name)实际会优先调用School.__init__ - 但
School.__init__仅接收1个位置参数school_name,传入2个参数会直接触发参数不匹配报错;就算临时调整参数数量,School的构造方法中也没有调用super().__init__(),调用链到School就中断,永远不会执行Exam.__init__,_exam_name属性自然无法初始化。
修复方案(坚持使用super()实现)
核心调整逻辑是:所有父类构造方法都适配多继承的参数传递规则,用关键字参数提取自身需要的属性后,将剩余参数通过super()传递给MRO链上的下一个类。修改后的完整代码如下:
class School: def __init__(self, school_name, **kwargs): self._school = school_name # 调用MRO链上下一个类的__init__方法 super().__init__(**kwargs) class Exam: def __init__(self, exam_name, **kwargs): self._exam_name = exam_name # 调用MRO链上下一个类的__init__方法 super().__init__(**kwargs) def credit(self): return 3 class Test(School, Exam): def __init__(self, school_name, exam_name): self._date = "Oct 7" # 用关键字参数传值,避免位置参数顺序和MRO不匹配导致的赋值错误 super().__init__(school_name=school_name, exam_name=exam_name) test = Test('Success', 'Math') print(test._school) # 输出 Success print(test._exam_name) # 输出 Math
调整点说明
- 给
School和Exam的__init__方法新增**kwargs参数,接收所有额外传入的关键字参数 - 每个父类构造方法执行完自身逻辑后,都新增
super().__init__(**kwargs)调用,把剩余参数传递给继承链的下一个类 - 子类调用
super().__init__时统一用关键字参数传值,避免参数顺序混乱问题
内容的提问来源于stack exchange,提问作者jam-butter-scone-tea
相关产品推荐
相关产品推荐

