You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

子类新增属性时为何需调用父类__init__方法?

为什么子类重写__init__后必须调用父类__init__?

你误解了方法解析顺序(MRO)的作用——MRO是当你调用某个方法时,如果当前类没有实现该方法,才会按顺序去父类查找对应的方法。但如果子类自己定义了__init__,Python会直接执行子类的__init__,不会自动触发父类的__init__。

拿你遇到的场景举例,代码大致是这样:

class Parent:
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name

class Child(Parent):
    def __init__(self, email):
        self.email = email

# 实例化后调用属性
child = Child("test@example.com")
print(child.first_name)  # 触发AttributeError

报错的核心原因是:子类的__init__完全覆盖了父类的__init__。创建Child实例时,只会执行子类里的初始化逻辑,父类的__init__根本没被运行过,first_name和last_name这两个属性从未被初始化到实例中,自然找不到。

MRO的逻辑是针对属性或方法的查找,但前提是这些属性已经被初始化出来。你以为Python会自动去父类的__init__里找属性,这是混淆了“方法调用”和“属性初始化”的逻辑——父类的__init__不执行,实例里就不会有那些属性,MRO再怎么找也找不到不存在的东西。

解决这个问题的方法很直接,在子类的__init__里主动调用父类的初始化方法,有两种常用方式:

  • 直接调用父类的__init__:
class Child(Parent):
    def __init__(self, first_name, last_name, email):
        Parent.__init__(self, first_name, last_name)
        self.email = email
  • 使用super()(更推荐,尤其是多继承场景):
class Child(Parent):
    def __init__(self, first_name, last_name, email):
        super().__init__(first_name, last_name)
        self.email = email

这样实例化子类时,父类的__init__会先执行,初始化first_name和last_name,子类再完成自己的email属性初始化,之后调用这些属性就不会报错了。

内容的提问来源于stack exchange,提问作者user20150947

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 19:56:50