
__new__与__init__:职责与执行顺序
在Python中,当我们创建一个类的实例时,解释器会按照特定的顺序调用两个特殊方法:
-
*`new(cls, args, kwargs)`:
- 这是一个类方法(尽管它没有@classmethod装饰器,但其第一个参数约定为cls,代表当前正在实例化的类)。
- 它的主要职责是创建并返回一个新的类实例。它是真正意义上的构造器,在对象被创建之前调用。
- 它必须返回一个实例,通常是cls的实例,或者cls的子类的实例。
-
*`init(self, args, kwargs)`:
- 这是一个实例方法。
- 它的主要职责是初始化新创建的实例。它接收__new__方法返回的实例作为self参数,然后对该实例的属性进行设置。
- __init__方法不应该返回任何值(隐式返回None)。
执行顺序总结: 当执行MyClass()时,Python首先调用MyClass.__new__来创建实例。如果__new__成功创建并返回了一个MyClass的实例(或其子类的实例),那么Python接下来会调用该实例的MyClass.__init__方法来对其进行初始化。
__new__返回值的关键作用
__new__方法的返回值至关重要。如果__new__方法没有返回当前类的实例(或者其子类的实例),那么__init__方法将不会被调用。最常见的情况是,如果__new__返回None,那么__init__将不会被执行,并且最终的变量会是None。
立即学习“Python免费学习笔记(深入)”;
考虑以下示例代码,它展示了__new__返回None时的行为:
class Demo:
def __new__(cls): # 正确的参数名是cls
print("Demo's __new__() invoked")
# 这里没有返回实例,等同于隐式返回 None
# return None
def __init__(self):
print("Demo's __init__() invoked")
def main():
obj = Demo()
print(f"obj is: {obj}")
main()输出:
Demo's __new__() invoked obj is: None
从输出可以看出,__new__被调用了,但__init__没有被调用,因为__new__没有返回一个Demo的实例。变量obj最终被赋值为None。
继承与__new__的错误实践分析
原始问题中的代码展示了一个常见的误区,其中__new__的第一个参数被错误地命名为self而不是cls,并且在__new__内部显式调用了`










