Python高级技术之：`Python`的`__new__`和`__init__`：对象创建与初始化的生命周期。

admin
Mon, 18 Aug 2025 15:17:55 +0000
Python, new, python

各位观众老爷，晚上好！我是你们的老朋友，今天咱们来聊聊Python里一对儿形影不离的好兄弟，__new__ 和 __init__。这对兄弟负责对象的创建和初始化，掌握了它们，你就能更深入地理解Python的面向对象编程，写出更灵活、更强大的代码。准备好了吗？咱们这就开始！ 第一幕：对象诞生的秘密——__new__的舞台 要理解__new__，首先要明白，在Python中，一切皆对象。类本身也是对象，称为类对象。当你用ClassName()来创建一个类的实例时，幕后发生的事情远比你看到的要复杂。__new__就是第一个出场的角色。 __new__是一个静态方法（注意，是静态方法，不是实例方法，也不是类方法！），它的作用是创建并返回一个类的实例。 它接受类本身作为第一个参数（通常命名为cls），以及创建对象所需的其他参数。如果__new__没有正确地返回一个实例，那么后续的__init__方法就不会被调用。 你可以把__new__想象成是盖房子的地基，它负责打好基础，准备好建造房屋的“原材料”（也就是未初始化的对象）。 举个栗子： class MyClass: def __new__(cl …

继续阅读“Python高级技术之：`Python`的`__new__`和`__init__`：对象创建与初始化的生命周期。”

The post Python高级技术之：`Python`的`__new__`和`__init__`：对象创建与初始化的生命周期。 first appeared on 智猿学院-前后端，数据库，人工智能，云计算等领域前沿技术讲座.

各位观众老爷，晚上好！我是你们的老朋友，今天咱们来聊聊Python里一对儿形影不离的好兄弟，__new__ 和 __init__。这对兄弟负责对象的创建和初始化，掌握了它们，你就能更深入地理解Python的面向对象编程，写出更灵活、更强大的代码。准备好了吗？咱们这就开始！

第一幕：对象诞生的秘密——__new__的舞台

要理解__new__，首先要明白，在Python中，一切皆对象。类本身也是对象，称为类对象。当你用ClassName()来创建一个类的实例时，幕后发生的事情远比你看到的要复杂。__new__就是第一个出场的角色。

__new__是一个静态方法（注意，是静态方法，不是实例方法，也不是类方法！），它的作用是创建并返回一个类的实例。 它接受类本身作为第一个参数（通常命名为cls），以及创建对象所需的其他参数。如果__new__没有正确地返回一个实例，那么后续的__init__方法就不会被调用。

你可以把__new__想象成是盖房子的地基，它负责打好基础，准备好建造房屋的“原材料”（也就是未初始化的对象）。

举个栗子：

class MyClass:
    def __new__(cls, *args, **kwargs):
        print("我是__new__，我正在创建对象...")
        instance = super().__new__(cls)  # 重点！调用父类的__new__来真正创建对象
        print("__new__创建对象完成！")
        return instance

    def __init__(self, name):
        print("我是__init__，我正在初始化对象...")
        self.name = name
        print("__init__初始化对象完成！")

obj = MyClass("张三")
print(obj.name)

运行结果大概是这样的：

我是__new__，我正在创建对象...
__new__创建对象完成！
我是__init__，我正在初始化对象...
__init__初始化对象完成！
张三

在这个例子中，__new__负责创建MyClass的实例，并将其返回。关键的一点是，必须调用父类（通常是object）的__new__方法来真正创建对象。 如果你不调用super().__new__(cls)，那么MyClass的实例就不会被真正创建出来，__init__也不会被调用。

重点：

__new__是静态方法。

__new__负责创建对象，并返回该对象。

必须调用super().__new__(cls)来真正创建对象。

如果__new__没有返回一个实例，__init__不会被调用。

第二幕：对象的华丽变身——__init__的妙手

当__new__创建好对象后，__init__就登场了。__init__是一个实例方法，它的作用是初始化对象的状态。 它接受对象本身作为第一个参数（通常命名为self），以及初始化对象所需的其他参数。

你可以把__init__想象成是房屋的装修队，它负责给房子添砖加瓦，让房子变得更加舒适和实用。

继续上面的栗子，__init__负责初始化MyClass实例的name属性。

class MyClass:
    def __new__(cls, *args, **kwargs):
        print("我是__new__，我正在创建对象...")
        instance = super().__new__(cls)
        print("__new__创建对象完成！")
        return instance

    def __init__(self, name):
        print("我是__init__，我正在初始化对象...")
        self.name = name
        print("__init__初始化对象完成！")

obj = MyClass("张三")
print(obj.name)

在这个例子中，__init__接收了name参数，并将其赋值给self.name，从而初始化了MyClass实例的name属性。

重点：

__init__是实例方法。

__init__负责初始化对象的状态。

__init__的第一个参数是self，指向对象本身。

第三幕：兄弟齐心，其利断金——__new__和__init__的合作

__new__和__init__就像一对默契的搭档，__new__负责创建对象，__init__负责初始化对象。它们协同工作，才能完成一个对象的完整创建过程。

总结一下它们的职责分工：

方法 | 职责 | 什么时候调用 | 返回值
__new__ | 创建并返回类的实例。它是静态方法，负责分配内存空间，创建对象。如果__new__没有返回一个实例，__init__就不会被调用。 | 在类被调用（例如 MyClass()）时，在 __init__ 之前被调用。 | 必须返回类的实例。通常通过调用 super().__new__(cls) 来创建实例。如果返回其他类型的对象，则会尝试将返回的对象传递给__init__方法，如果类型不兼容，会报错。也可以返回None，则创建过程提前结束。
__init__ | 初始化对象的状态。它是实例方法，负责设置对象的属性，进行必要的配置。 | 在 __new__ 返回类的实例后，立即被调用。如果 __new__ 没有返回实例，__init__ 就不会被调用。 | 通常返回 None。虽然可以返回其他值，但会被忽略，并且会发出 DeprecationWarning 警告。

第四幕：高级应用——__new__的特殊用途

虽然__init__更常见，但__new__也有一些特殊的用途，掌握这些用途，能让你写出更灵活的代码。

1. 创建不可变对象：

对于不可变对象（例如元组、字符串），一旦创建，就不能修改其状态。因此，初始化过程需要在创建时完成。这时候，__new__就派上用场了。

class ImmutableClass:
    def __new__(cls, value):
        instance = super().__new__(cls)
        instance.value = value
        return instance

    def __init__(self, value):
        # 实际上，__init__ 在这里不会被调用，因为所有初始化工作都在 __new__ 中完成了
        print("__init__ 被调用了，但是这里不会执行任何操作")  # 永远不会被打印

obj = ImmutableClass(10)
print(obj.value)
# obj.value = 20  # AttributeError: can't set attribute

在这个例子中，ImmutableClass的value属性在__new__中被设置，并且没有提供任何修改value属性的方法，因此ImmutableClass的实例是不可变的。 __init__方法虽然定义了，但并不会被调用。

2. 实现单例模式：

单例模式是一种设计模式，它保证一个类只有一个实例，并提供一个全局访问点。__new__可以用来实现单例模式。

class Singleton:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance

obj1 = Singleton()
obj2 = Singleton()

print(obj1 is obj2)  # True，说明 obj1 和 obj2 是同一个实例

在这个例子中，Singleton类维护了一个_instance属性，用于存储唯一的实例。在__new__方法中，首先检查_instance是否为空，如果为空，则创建一个新的实例并赋值给_instance，否则直接返回_instance。这样，无论创建多少个Singleton的实例，都只会返回同一个实例。

3. 控制对象创建过程：

__new__可以用来控制对象创建过程，例如，可以根据不同的参数创建不同类型的对象。

class Shape:
    def __new__(cls, shape_type, *args, **kwargs):
        if shape_type == "circle":
            return Circle(*args, **kwargs)
        elif shape_type == "square":
            return Square(*args, **kwargs)
        else:
            raise ValueError("不支持的形状类型")

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

class Square(Shape):
    def __init__(self, side):
        self.side = side

circle = Shape("circle", 5)
square = Shape("square", 10)

print(type(circle))  # <class '__main__.Circle'>
print(type(square))  # <class '__main__.Square'>
print(circle.radius) # 5
print(square.side) # 10

在这个例子中，Shape类的__new__方法根据shape_type参数的不同，创建不同类型的对象（Circle或Square）。

4. 修改对象的类：

虽然不常见，但__new__甚至可以返回一个不同于当前类的实例。

class A:
    def __new__(cls):
        return B() # 返回B的实例，而不是A的实例

    def __init__(self):
        print("A's init")

class B:
    def __init__(self):
        print("B's init")

obj = A() # 注意这里，虽然创建的是A的对象，但实际上得到的是B的对象
print(type(obj)) # <class '__main__.B'>

在这个例子中，A的__new__方法返回了B的一个实例。因此，虽然我们试图创建一个A的实例，但实际上我们得到的是一个B的实例。注意，A的__init__方法不会被调用，而是调用B的__init__方法。

第五幕：踩坑指南——__new__的注意事项

虽然__new__很强大，但使用不当也会导致一些问题。

1. 忘记调用super().__new__(cls)：

这是最常见的错误。如果你没有调用super().__new__(cls)，那么类的实例就不会被真正创建出来，__init__也不会被调用。

2. __new__返回了错误类型的对象：

__new__必须返回类的实例（或者是子类的实例）。如果返回了其他类型的对象，可能会导致类型错误。

3. 在__new__中过度初始化对象：

虽然可以在__new__中初始化对象，但最佳实践是将初始化工作放在__init__中进行。__new__的主要职责是创建对象，而不是初始化对象。

总结：

__new__和__init__是Python面向对象编程中非常重要的两个方法。__new__负责创建对象，__init__负责初始化对象。掌握了这两个方法，你就能更深入地理解Python的面向对象编程，写出更灵活、更强大的代码。

希望今天的讲座对大家有所帮助。记住，编程之路，没有捷径，唯有勤学苦练。 下次有机会再跟大家分享其他的技术知识。 拜拜！