在 Python 中,__new__
是一个特殊的静态方法,用于控制类的实例创建过程,它是类实例化时第一个被调用的方法(早于 __init__
)。通过重写 __new__
,可以实现对对象创建行为的精细控制,例如创建单例、定制不可变对象或修改实例的生成逻辑。
核心作用与原理
-
实例创建入口
__new__
负责创建并返回类的实例对象,而__init__
仅负责初始化该实例的属性。class MyClass: def __new__(cls, *args, **kwargs): instance = super().__new__(cls) # 必须调用父类的 __new__ 创建实例 print("创建实例") return instance # 返回实例后,__init__ 才会执行 def __init__(self): print("初始化实例")
-
与
__init__
的区别__new__
是静态方法,第一个参数是类(cls
),返回实例对象。__init__
是实例方法,第一个参数是实例(self
),无返回值。- 若
__new__
未返回实例,__init__
将不会被调用。
典型应用场景
1. 实现单例模式(Singleton)
通过 __new__
控制实例的唯一性,确保类只有一个实例存在:
class Singleton:
_instance = None
def __new__(cls):
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance
a = Singleton()
b = Singleton()
print(a is b) # 输出 True(a 和 b 是同一个对象)
2. 定制不可变类型
不可变类型(如 int
, str
, tuple
)的实例在创建后无法修改。通过 __new__
可以在创建时固定值:
class ImmutableStr(str):
def __new__(cls, value):
# 在创建时修改或限制值的生成逻辑
instance = super().__new__(cls, value.upper())
return instance
s = ImmutableStr("hello")
print(s) # 输出 "HELLO"
3. 子类化不可变类型
当继承不可变类型(如 tuple
)时,需在 __new__
中初始化数据,因为 __init__
无法修改不可变对象:
class CustomTuple(tuple):
def __new__(cls, items):
# 过滤掉非整数元素
filtered = (x for x in items if isinstance(x, int))
return super().__new__(cls, filtered)
t = CustomTuple([1, "a", 3.5, 5])
print(t) # 输出 (1, 5)
4. 动态选择子类
在工厂模式中,根据参数动态创建不同的子类实例:
class Shape:
def __new__(cls, shape_type, *args):
if shape_type == "circle":
return Circle(*args)
elif shape_type == "square":
return Square(*args)
else:
raise ValueError("Unknown shape")
class Circle:
def __init__(self, radius):
self.radius = radius
class Square:
def __init__(self, side):
self.side = side
circle = Shape("circle", 5)
print(circle.radius) # 输出 5
注意事项
-
必须返回实例对象
__new__
必须返回一个有效的实例(通常是调用父类的__new__
),否则__init__
不会执行。 -
与元类的区别
__new__
属于类级别,用于控制实例创建;元类(__metaclass__
)则用于控制类的创建行为(更底层)。 -
谨慎重写
大多数情况下无需重写__new__
,优先使用__init__
进行初始化。仅在需要控制实例创建逻辑时使用。
总结
__new__
是 Python 中对象创建的底层机制,通过它可实现单例、不可变对象定制、工厂模式等高级功能,是深入理解 Python 面向对象编程的关键方法之一。
(以上内容由 AI 生成)