详解 Python 中 __new__ 与 __init__ 的区别与联系

林舟
林舟
发布时间:2026-10-12 | 1人浏览过
原创

本文详细解析 Python 中 __new__ 与 __init__ 的核心差异与协同工作流程。通过明确两者在内存分配与属性初始化中的分工,对比函数签名、调用时机与返回值特征,并结合标准类定义示例,阐明如何正确重写这两个特殊方法以实现自定义对象构造及进阶控制。

对象创建流程与核心机制

第1步:确认底层调用顺序与职责划分

在 Python 实例化过程中,解释器严格遵循先创建后初始化的顺序。调用类名构造函数时,首先触发 __new__ 方法负责内存分配并返回一个全新的类实例;随后解释器自动将该实例作为参数传递给 __init__ 方法进行属性赋值与状态绑定。__new__ 属于静态方法范畴,处理对象的物理创建;__init__ 属于实例方法,处理逻辑初始化。两者缺一不可,共同完成完整的实例化生命周期。

第2步:核对参数签名与返回值规范

两者的函数定义存在显著差异,重写时必须严格遵循:
- __new__(cls, *args, **kwargs):第一个参数固定为当前类(cls),用于接收实例化时的传入参数。该方法必须显式返回一个实例对象,否则后续的 __init__ 不会执行。
- __init__(self, *args, **kwargs):第一个参数固定为生成的实例本身(self),同样接收构造参数。该方法仅用于修改对象状态,隐式返回 None,切勿在末尾添加 return 语句导致异常。

重写逻辑与标准代码实现

第3步:配置类定义与依赖调用关系

日常开发中多数情况无需手动覆写这两个方法。当涉及不可变类型定制、单例模式实现或元类干预时,才需介入重写。覆盖 __new__ 的标准做法是调用父类同名方法获取实例,随后在 __init__ 中安全地设置属性。两者通过返回值链路相互依赖:__new__ 产出的对象会自动注入 __init__ 的 self 参数中。

class CustomObject:
    def __new__(cls, *args, **kwargs):
        # 调用基类 object.__new__ 分配内存并返回新实例
        instance = super().__new__(cls)
        return instance

    def __init__(self, name):
        # 接收 __new__ 返回的实例进行初始化
        self.name = name
        print(f"Instance created: {name}")

# 验证调用链路与输出结果
obj = CustomObject("Alice")
print(f"Attribute value: {obj.name}")

执行上述代码将依次打印创建提示与最终属性值。若在 __new__ 中直接返回已存在的旧实例(如实现单例),__init__ 仍会被调用一次,需注意属性覆盖风险。

功能验证与常见排错指南

第4步:检查实例状态与方法可用性

完成编写后,可通过以下要点快速排查逻辑断层:

  • 属性未生效:检查是否在 __init__ 中遗漏了 self. 前缀,或错误地在 __new__ 中进行了属性赋值。
  • TypeError 报错:确认参数数量是否匹配。若继承自特定类(如 dict 或 tuple),子类重写 __new__ 时需确保返回的实例类型与预期一致。
  • 无限递归:避免在 __new__ 中再次调用自身类名,必须使用 super() 或 object.__new__(cls) 切断循环。

以上就是Python中__new__与__init__区别与联系的具体应用与实现细节的详细内容,更多关于Python特殊方法与对象构造机制的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表