`__new__`是实例方法?还是类方法?或是静态方法?
__new__本质上是解释器硬编码的“类专属静态方法”。核心原因就一个:它是Python“对象创建协议”的核心,规则由解释器直接定义,不需要装饰器来“声明身份”。
我们可以用“排除法+本质拆解”把它说透:
第一步:先排除“它不是什么”
-
不是普通实例方法:
实例方法的第一个参数是self(代表已创建的实例),但__new__的作用是“创建实例”——实例还没诞生,哪来的self?所以它第一个参数是cls(当前类),根本不依赖实例,自然不是实例方法。 -
不是需要
@staticmethod的普通静态方法:
普通静态方法完全“独立”,调用时要手动传所有参数(比如MyClass.func(123))。但__new__调用时,解释器会自动把当前类作为cls传入(比如MyClass()会自动触发MyClass.__new__(MyClass)),不需要我们手动传cls,比普通静态方法多了“自动传类”的特殊待遇。 -
不是需要
@classmethod的普通类方法:
类方法的核心是“操作类本身”(比如修改类属性、做类工厂),返回值可以是任意东西;但__new__的核心是“必须返回一个实例”——这是强制要求,不返回实例的话,后续的__init__都不会执行。而且类方法需要@classmethod告诉解释器“自动传cls”,但__new__不用,因为解释器早就“认识”它了。
第二步:再看“它到底是什么”——解释器的“专属特例”
Python里有一批像__new__这样的“魔术方法”(以__开头结尾),它们的规则不是靠装饰器,而是靠解释器内置的协议:
- 比如
__init__,不用任何装饰器,解释器就知道要把__new__创建的实例当self传进去; - 比如
__call__,不用装饰器,解释器就知道实例调用时要传self; - 而
__new__,解释器的规则是:- 只有在“创建实例”(比如
MyClass())时才自动调用; - 调用时必须传
cls(当前类)作为第一个参数,且由解释器自动传,不用我们管; - 必须返回一个实例(否则实例创建失败)。
- 只有在“创建实例”(比如
这种“自动传cls、不用装饰器、专属类创建”的特性,本质是解释器给__new__开的“后门”——它不需要像普通方法那样靠装饰器声明类型,因为它是Python“造对象”的底层入口,规则早被写死在解释器里了。
第三步:用一个例子直观感受“特殊规则”
我们给__new__加个打印,看参数怎么来的:
class MyClass:
# 既没@staticmethod也没@classmethod
def __new__(cls, name): # cls自动传,不用我们写
print(f"__new__拿到的类:{cls}(就是MyClass本身)")
print(f"__new__拿到的参数:name={name}")
# 必须调用父类__new__造实例
instance = super().__new__(cls)
return instance
def __init__(self, name):
self.name = name
# 调用时,我们只传name,cls由解释器自动传
obj = MyClass("张三")
输出结果:
__new__拿到的类:<class '__main__.MyClass'>(就是MyClass本身)
__new__拿到的参数:name=张三
你看:我们调用MyClass("张三")时,只传了name,但__new__里的cls自动拿到了MyClass——这就是解释器的特殊处理,普通静态/类方法没这个待遇(普通静态方法得写MyClass.func(MyClass, "张三"),普通类方法得加@classmethod才自动传cls)。
最后一句话总结
__new__的“四不像”,本质是因为它是Python“对象创建流程”的“守门人”——解释器需要它必须按固定规则工作(自动传cls、返回实例),所以直接把规则内置了,不需要装饰器来“画蛇添足”。它更像“类专属的特殊静态方法”:既像静态方法那样不依赖实例,又像类方法那样自动传cls,但因为是底层协议,所以省了装饰器步骤。

浙公网安备 33010602011771号