__new__负责创建对象,__init__仅初始化;95%场景无需重写__new__,错误实现会导致__init__静默失效——仅当__new__返回本类或子类实例时才自动调用__init__。

__new__ 负责创建对象,__init__ 只负责初始化;95% 的场景你根本不需要碰 __new__,写错它反而会让 __init__ 静默失效。
为什么 __init__ 有时根本不执行?
最常见原因是 __new__ 返回了非本类实例,比如返回了父类对象、int 或 str 字面量,甚至 None。Python 规则很明确:只有当 __new__ 显式返回当前类(或其子类)的实例时,解释器才会自动调用该实例的 __init__。
- 错误示例:
return 42→__init__完全不触发,也不会报错,只默默跳过 - 正确写法必须包含:
super().__new__(cls)或等价的object.__new__(cls) - 若重写了
__new__却忘了return,实际返回None,后续调用会直接TypeError: __init__() missing 1 required positional argument
__new__ 是静态方法,但不用 @staticmethod 装饰
它第一个参数是 cls(类本身),不是 self——因为此时对象还没诞生。你不能在 __new__ 里访问 self.xxx,也不能给实例设属性(instance.xxx = ... 是允许的,但 self.xxx 会报错)。
-
__new__中禁止使用self,否则NameError: name 'self' is not defined - 想传参给
__init__?__new__的*args和**kwargs会原样透传过去,但你自己不能消费它们(除非你打算拦截并改写逻辑) - 继承不可变类型(如
str、tuple)时,必须在__new__里处理值,因为__init__在不可变对象上被忽略或无效
单例模式里 __new__ 怎么写才不出错?
单例不是靠“不重复初始化”实现的,而是靠“只创建一次实例”。关键点在于:判断逻辑在 __new__,而赋值逻辑仍在 __init__ —— 这会导致多次调用 __init__ 覆盖前值,是初学者高频翻车点。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 典型陷阱:
_instance已存在时仍让__init__执行,结果后建的对象把先建的属性冲掉了 - 安全做法:在
__new__里检查是否已存在,存在就直接返回旧实例;同时在__init__开头加守卫:if hasattr(self, '_initialized'):→return - 别用
is判断类是否已实例化,要用类变量(如cls._instance)做状态标记
日常开发中什么时候真得动 __new__?
绝大多数业务代码连看都不用看它。真正需要重写 __new__ 的情况非常窄:
立即学习“Python免费学习笔记(深入)”;
- 实现单例、对象池、缓存实例(如连接池中的 connection 复用)
- 继承
int/str/tuple等不可变类型,并想控制构造行为(例如:强制转正、截断长度) - ORM 或序列化框架底层,需根据数据动态决定实例化哪个子类(工厂式创建)
- 元编程场景,配合
__metaclass__或__init_subclass__做类生成干预
容易被忽略的是:一旦你重写了 __new__,就必须确保它始终返回一个合法对象,且和预期类一致;否则 __init__ 的调用链就断了,问题往往表现为“对象属性不存在”或“方法调用失败”,但 traceback 里完全不提 __new__ —— 因为它根本没报错,只是静默绕过了初始化。

















