__init__
大家都熟,但 __new__
呢? 很多 Python 开发者对 __new__
要么一无所知,要么理解片面。 但在你写单例、不可变对象、甚至高级元类的时候,__new__
是你必须掌握的底层机制。 本文用通俗易懂的语言、实战代码和应用场景,带你彻底弄清这对“Python 双胞胎”的差异和联系!
🧠 __init__
是“初始化”,__new__
是“创造生命”
先记住最核心的结论:
__new__
负责“创建”对象
__init__
负责“初始化”对象
换句话说:
obj=MyClass()
这个过程中,实际发生了两步:
MyClass.__new__()
→ 创建对象
MyClass.__init__()
→ 初始化对象属性
🛠 一段代码感受执行顺序
classDemo:
def__new__(cls, *args, **kwargs):
print("执行 __new__")
instance=super().__new__(cls)
returninstance
def__init__(self, x):
print("执行 __init__")
self.x=x
d=Demo(10)
输出:
markdown复制编辑执行 __new__
执行 __init__
✔️ 看到了吗?__new__
总是先于 __init__
被调用!
🤔 那我们为什么几乎从不写 __new__
?
因为大部分情况下,我们只需要初始化就够了,对象创建这一步交给 Python 内部就行了。
但是在某些特殊场景下,我们必须亲自出手干预对象的创建过程,这时 __new__
就派上用场了!
✅ 场景一:不可变对象(如自定义 str、tuple 子类)
classMyStr(str):
def__new__(cls, content):
print("在 __new__ 中处理内容")
returnsuper().__new__(cls, content.upper())
s=MyStr("hello")
print(s) # 输出:HELLO
由于 str
是不可变类型,只能在 __new__
中修改内容。
✅ 场景二:实现单例模式
classSingleton:
_instance=None
def__new__(cls, *args, **kwargs):
ifcls._instanceisNone:
cls._instance=super().__new__(cls)
returncls._instance
__new__
是控制是否创建新对象的关键点,非常适合做单例设计。
✅ 场景三:元类编程、自定义对象生成逻辑
高级用法:使用元类(metaclass)控制类的创建行为,本质上也是通过重写 __new__
。
🔍 __new__
和 __init__
的区别一图胜千言:
特性 | __new__ |
__init__ |
---|
作用 | 创建对象 | 初始化对象 |
返回值 | 必须返回实例对象 | 无需返回值 |
调用时机 | 在 __init__ 之前 | 在对象创建之后 |
用于哪些类型 | 所有类(尤其是不可变类型) | 所有类 |
使用频率 | 较少,仅限高级使用场景 | 非常常见 |
🧩 冷知识:这些你可能还不知道
如果 __new__
返回的不是当前类实例,__init__
将不会被调用。
__new__
是一个类方法(第一个参数是 cls
),而 __init__
是实例方法(第一个参数是 self
)。
在继承结构中,如果重写了 __new__
,要记得调用 super().__new__(cls)
保证对象能正常创建。
📌 写在最后
你可能不需要每次都写 __new__
, 但如果你要构建高阶 API、做架构封装、编写底层库——你必须真正理解它。
正所谓:
“Python 的优雅,不在于你写了多少类,而在于你是否真正掌握了对象的生命周期。”
如果这篇文章让你恍然大悟,请点赞、转发,或者分享给那些你想一起进阶的 Python 同伴吧!
对Python,AI,自动化办公提效,副业发展等感兴趣的伙伴们,扫码添加逍遥,限免交流群
备注【成长交流】