__new__返回实例类型必须与类一致,否则跳过__init__;__init__中不能重赋值self;单例需在__new__缓存并返回旧实例;不可变类型构造必须在__new__完成。

为什么__new__返回的实例类型必须和类一致
如果__new__返回了非当前类或其子类的实例(比如直接返回int(42)或object()),Python 会跳过__init__调用——这不是 bug,是语言设计:只有当__new__返回的是本类实例时,解释器才认为“构造完成”,进而触发__init__。常见错误是写成:
def __new__(cls, value):
return super().__new__(int) # 错!返回 int 实例,__init__ 不会被调用
正确做法是确保返回cls的实例:
def __new__(cls, value):
instance = super().__new__(cls)
return instance
如果你真要代理到其他类型(如单例、缓存、不可变封装),必须显式调用__init__或改用__call__在元类中控制。
__init__里不能给self重新赋值为新对象
__init__的self参数是__new__返回的对象引用,它已经确定了内存地址和类型。你不能在__init__里写self = SomeOtherClass()——这只会让局部变量self指向别处,原对象不变,且后续所有属性赋值都作用在旧对象上。
典型误用场景:
- 想“转换类型”:比如传入字符串就转成
int,但又想保留类接口 → 应该在__new__中决定返回哪个类的实例,或用工厂函数 - 想避免重复初始化:比如检查参数是否已存在对应实例 → 这属于对象创建逻辑,应在
__new__中做缓存/查表
记住:__init__只负责“填充”已有实例,不负责“生成”或“替换”。
Python 环境工具专业版功能概述Python 环境工具专业版是一项面向实际任务的技能。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。核心要点使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。执行完成后建议检查结果是否符合预期,并保留必要记录。使用与执行同时注意输入完整性、执行条件和输出可用性。从功能定位来看,该技能
单例模式下__new__必须缓存并返回旧实例
单例不是靠__init__控制的,因为每次调用类都会执行__new__→__init__流程。__init__反复执行会导致状态被覆盖。真正可靠的单例必须在__new__中拦截:
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
注意两点:
- 缓存的是
cls._instance,不是self(self还没诞生) - 必须用
super().__new__(cls)而非object.__new__(cls),否则绕过父类__new__可能破坏继承链(比如某些框架类重写了__new__)
如果类有参数,还要在__new__中处理**kwargs或校验参数一致性,否则多次不同参数调用可能导致状态混乱。
不可变类型(如str、tuple子类)必须在__new__中完成构造
__init__无法修改不可变对象的值。例如自定义一个带校验的PositiveInt:
int
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










