必须用__new__的场景:实现单例模式、子类化不可变类型(如tuple/str/int)、绕过默认内存分配;__new__负责创建并返回实例,必须调用父类__new__,且不能在其中赋值属性。

绝大多数情况下,你只需要定义 __init__;__new__ 仅在需要控制实例创建过程(比如单例、不可变类型、自定义内存分配)时才动手改。
什么时候必须用 __new__?
__new__ 是真正的“构造器”,它负责返回一个新实例;__init__ 只是“初始化器”,在实例已存在后被调用。常见必须重写 __new__ 的场景:
- 实现单例模式(返回已有实例,而非新建)
- 子类化
tuple、str、int等不可变类型时,因为它们的值在创建后不能修改,必须在__new__中确定 - 需要绕过默认内存分配(极少见,如与 C 扩展交互)
错误做法:在 __new__ 里做属性赋值(如 self.x = 1),此时对象可能还没完全构建好;这类逻辑应严格放在 __init__ 中。
__new__ 必须返回实例,且要调用父类 __new__
如果你重写了 __new__,但没显式调用 super().__new__(cls) 或等价形式,Python 就不会为你创建对象——结果通常是 None,接着触发 TypeError: __init__() missing 1 required positional argument 这类看似奇怪的报错。
正确写法示例(单例):
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls) # ← 关键:必须调用父类 __new__
return cls._instance
<pre class="brush:php;toolbar:false;">def __init__(self):
# 这里可以安全地初始化,但要注意:__init__ 每次都会执行!
pass
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
注意:__init__ 在每次调用 Singleton() 时都会运行,哪怕返回的是旧实例——所以单例中常需加标志位避免重复初始化。
__init__ 不该返回值,__new__ 不能忽略参数
__init__ 的返回值会被静默丢弃,如果误写 return self 或 return True,不仅无意义,还可能掩盖逻辑错误。
__new__ 的第一个参数必须是 cls,且必须接收并传递后续参数给父类(如果父类 __new__ 需要它们)。例如子类化 str:
class MyStr(str):
def __new__(cls, content):
# 必须把 content 传给父类 str.__new__
instance = super().__new__(cls, content)
return instance
漏掉 content 会导致 TypeError: str() takes at most 1 argument。
真正容易被忽略的是:即使你只改了 __new__,也得确认 __init__ 是否仍被预期调用;某些极端定制(如返回非本类实例)会让 __init__ 根本不执行——这时候初始化逻辑就得全挪进 __new__ 里,且要格外小心对象状态一致性。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










