Python __new__ 方法
最后修改于 2025 年 4 月 8 日
本综合指南探讨了 Python 的 __new__
方法,这是负责对象创建的特殊方法。我们将涵盖基本用法、不可变对象、单例模式、元类以及实际示例。
基本定义
__new__
方法是一个静态方法,用于创建并返回类的新实例。它在 __init__
之前被调用,并负责对象分配。
关键特征:它必须接受类作为第一个参数(通常命名为 cls
),返回新实例,并且可以被重写以自定义对象创建。与 __init__
不同,它控制创建过程。
基本 __new__ 实现
这是展示 __new__
在对象创建生命周期中作用的最简单实现。它演示了它如何与 __init__
一起工作。
class Example: def __new__(cls, *args, **kwargs): print("__new__ called") instance = super().__new__(cls) return instance def __init__(self, value): print("__init__ called") self.value = value obj = Example(42) print(obj.value)
此示例展示了对象创建的顺序。__new__
创建实例,然后 __init__
初始化它。输出将在“__init__ called”之前显示“__new__ called”。
super().__new__(cls)
调用至关重要——它使用父类的 __new__
方法(通常是 object.__new__
)来创建实际的实例。
创建不可变对象
在创建元组或自定义不可变类等不可变类型时,__new__
是必不可少的,因为它可以防止创建后进行修改。
class ImmutablePoint: def __new__(cls, x, y): instance = super().__new__(cls) instance._x = x instance._y = y return instance @property def x(self): return self._x @property def y(self): return self._y def __repr__(self): return f"Point({self.x}, {self.y})" point = ImmutablePoint(3, 4) print(point) # point.x = 5 # Would raise AttributeError
这个不可变点类通过 __new__
在创建时设置坐标,并通过只读属性暴露它们。尝试修改它们将引发 AttributeError
。
实例变量在返回实例之前在 __new__
中设置,使其成为初始对象状态的一部分。这种模式对于不可变对象很常见。
实现单例模式
单例模式确保一个类只有一个实例。__new__
可以通过控制实例创建来强制执行此操作。
class Singleton: _instance = None def __new__(cls): if cls._instance is None: print("Creating new instance") cls._instance = super().__new__(cls) return cls._instance def __init__(self): print("Initializing Singleton") s1 = Singleton() s2 = Singleton() print(s1 is s2) # True
此单例实现将单个实例存储在类变量中。__new__
在创建新实例之前检查它是否存在。所有构造函数调用都返回相同的实例。
请注意,__init__
每次都会被调用,这可能会重新初始化实例。为防止这种情况,您可以添加另一个标志或重构代码。
使用参数自定义对象创建
__new__
可以检查参数并决定是否/如何创建实例,从而实现高级创建模式。
class LimitedInstances: _count = 0 MAX_INSTANCES = 3 def __new__(cls, *args, **kwargs): if cls._count >= cls.MAX_INSTANCES: raise RuntimeError(f"Cannot create more than {cls.MAX_INSTANCES} instances") cls._count += 1 return super().__new__(cls) def __del__(self): type(self)._count -= 1 objs = [LimitedInstances() for _ in range(3)] # Works # LimitedInstances() # Raises RuntimeError
此类将活动实例的数量限制为 3。__new__
在允许创建之前检查计数。当实例被垃圾回收时,__del__
方法会减少计数。
这种模式对于资源受限的场景很有用,例如数据库连接或线程池,您希望强制执行实例限制。
元类 __new__ 方法
在元类中,__new__
控制类创建(而不是实例创建),允许动态修改类。
class Meta(type): def __new__(mcls, name, bases, namespace): print(f"Creating class {name}") namespace['version'] = 1.0 return super().__new__(mcls, name, bases, namespace) class MyClass(metaclass=Meta): pass print(MyClass.version) # 1.0
这个元类为它创建的每个类添加一个 version
属性。元类的 __new__
在类被构造之前修改类命名空间。
元类 __new__
接收不同的参数:元类本身、类名、基类以及包含类属性的命名空间字典。
最佳实践
- 始终调用 super().__new__: 除非有意阻止创建
- 返回正确类型: 确保返回的对象是 cls 的实例
- 考虑 __init__: __new__ 中的更改可能会影响初始化
- 记录行为: 清楚地记录任何特殊的创建逻辑
- 尽可能优先使用 __init__: 仅在必要时使用 __new__
资料来源
作者
列出所有 Python 教程。