Python类继承调用super().__init__时为何出现父类参数缺失报错?
报错成因
- 你写的第一段可运行代码本身存在写法错误,只是被父类参数默认值掩盖才没崩溃:用
super()调用父类实例方法时,不需要手动传入self。super()返回的代理对象会自动绑定当前子类实例,隐式完成self的传参。你写的super().__init__(self)实际只给父类__init__传了1个位置参数(就是当前子类实例本身),刚好原来父类的last_name设有默认值,参数数量刚好凑够:传入的实例被赋值给first_name参数,last_name走默认值"Fish",后续你手动写terry.first_name = "Terry"只是覆盖了之前错误赋的实例值,本质初始化逻辑是错的。 - 删掉父类
last_name的默认值后,父类__init__要求必须传入2个必填位置参数:first_name和last_name。但子类里仍然只写了super().__init__(self),仅传入1个参数,缺少必填的last_name,因此抛出TypeError: Fish.__init__() missing 1 required positional argument: 'last_name'。
子类自定义last_name的正确实现
核心原则:调用super().__init__()时不要手动传self,按照父类的参数要求传够对应的值即可,根据业务场景可以选两种常见实现方式:
方式1:实例化时动态传入姓名参数
适合每个实例的first_name、last_name都不固定的场景,子类初始化方法接收对应参数后透传给父类:
class Fish: def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name class Trout(Fish): def __init__(self, first_name, last_name, water = "freshwater"): self.water = water # 按父类参数要求传值,无需传self super().__init__(first_name, last_name) # 实例化时直接传入所有需要的属性值,不需要后续手动补赋值 terry = Trout(first_name="Terry", last_name="Crews") print(terry.first_name + " " + terry.last_name) # 输出:Terry Crews print(terry.water) # 输出:freshwater
方式2:给不同子类设置固定默认last_name
如果同一子类的last_name是固定值(比如所有鳟鱼的last_name统一为Trout,三文鱼统一为Salmon),可以在子类调用父类初始化时直接传入固定值:
class Fish: def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name class Trout(Fish): def __init__(self, first_name, water = "freshwater"): self.water = water # 固定传入当前子类的默认last_name super().__init__(first_name, last_name="Trout") class Salmon(Fish): def __init__(self, first_name, water = "freshwater"): self.water = water super().__init__(first_name, last_name="Salmon") terry = Trout(first_name="Terry") print(terry.last_name) # 输出:Trout sam = Salmon(first_name="Sam") print(sam.last_name) # 输出:Salmon
注意:除非有特殊的动态属性需求,不建议实例化之后再手动给对象赋值
first_name、last_name这类核心属性,应该在__init__初始化阶段就完成赋值,避免出现属性未定义的异常。
内容的提问来源于stack exchange,提问作者mxnlearnspython
相关产品推荐
相关产品推荐

