python继承中,__new__负责创建实例并决定是否调用__init__,后者需显式调用父类版本;单继承用super(),多重继承须遵循mro协作调用。

Python 中继承关系下的实例初始化,核心在于对象创建和属性初始化两个阶段的配合,且二者职责分明:__new__ 负责生成实例,__init__ 负责填充数据。父类的 __init__ 不会自动执行,必须显式触发。
__new__ 先于 __init__,且决定是否进入初始化
实例化时,首先调用 __new__(静态方法),它负责分配内存并返回一个该类的实例。只有当 __new__ 返回的是当前类或其子类的实例时,Python 才会自动调用该实例的 __init__ 方法。若 __new__ 返回其他类型对象(如缓存实例、None 或其他类的实例),__init__ 将被跳过。
- 自定义 __new__ 时,通常需调用 super().__new__(cls) 获取本类实例
- 单例、对象池等模式中,__init__ 可能被多次调用——因 __new__ 返回了已有实例,此时需在 __init__ 内加防护逻辑(如检查属性是否存在)
__init__ 是初始化钩子,不调父类就等于没初始化
__init__ 本身只是普通实例方法,不是构造函数。子类若重写了 __init__,Python 不会隐式调用父类版本。遗漏 super().__init__() 会导致:
- 父类定义的实例属性(如 self.name、self.config)根本不存在,后续访问抛 AttributeError
- Mixin 类中的 setup 逻辑、装饰器依赖的初始化未运行
- 资源类(如打开文件、连接数据库)的初始化失败,引发运行时异常
单继承下推荐统一用 super()
在单继承结构中,super().__init__(...) 是最清晰、可维护性最强的方式:
- 避免硬编码父类名,利于后期重构(如修改继承链)
- 参数传递更自然:子类 __init__ 接收所需参数后,只把父类需要的部分传给 super()
- 示例:class Person(Animal):
def __init__(self, name, age, job):
super().__init__(name, age)
self.job = job
多重继承必须依赖 MRO 和 cooperative super()
当子类继承多个父类(如 class Child(A, B):)时,super().__init__() 不是指向某个固定父类,而是按 MRO 顺序 调用下一个类的 __init__。可通过 Child.__mro__ 查看实际顺序。
- 所有参与继承的类都应使用 super().__init__(...),形成“协作式调用链”,否则可能跳过某些父类或重复初始化
- 若某父类未使用 super()(如直接写 A.__init__(self)),链会在该处中断,后续父类不会被调用
- 典型错误:在多重继承中混用 Parent1.__init__(self) 和 super().__init__() —— 极易导致部分初始化遗漏或重复











