__init__
对比特性 | __new__ |
__init__ |
---|---|---|
方法类型 | 静态方法 | 实例方法 |
返回值 | 必须返回实例对象 | 无返回值 |
调用时机 | 创建实例时首先调用 | 在 __new__ 之后调用 |
主要职责 | 控制实例创建过程 | 初始化实例属性 |
元类中的 __new__
参数(示例 4.1)
class Meta(type):
def __new__(mcs, name, bases, attrs):
# 参数列表固定
return super().__new__(mcs, name, bases, attrs)
参数名 | 类型 | 说明 |
---|---|---|
mcs |
type |
元类自身(约定命名,类似 cls 代表类) |
name |
str |
要创建的类名(如 "MyClass" ) |
bases |
tuple |
基类列表(继承的父类) |
attrs |
dict |
类属性字典(包含方法、类变量等) |
super().__new__
最终调用 type.__new__
生成类对象不可变类型子类的 __new__
(示例 3.2)
class ImmutableStr(str):
def __new__(cls, value):
return super().__new__(cls, processed_value)
参数名 | 类型 | 说明 |
---|---|---|
cls |
type |
当前类对象(ImmutableStr ) |
value |
Any |
用户自定义参数(初始化输入值) |
str/int/tuple
等)__new__
完成实例创建super().__new__
调用父类(str
)的构造方法__new__
的要求(如 str
需要传入初始化字符串)可变类型普通类的 __new__
(示例 3.1)
class Singleton:
def __new__(cls, *args, **kwargs):
return super().__new__(cls)
参数名 | 类型 | 说明 |
---|---|---|
cls |
` | 当前类对象(Singleton ) |
*args |
tuple |
位置参数(与 __init__ 共享参数) |
**kwargs |
dict |
关键字参数(与 __init__ 共享参数) |
super().__new__
调用 object.__new__
生成实例__init__
方法兼容__new__
的四个参数是固定结构
__new__
第一个参数必为 cls
__init__
匹配super().__new__
的参数必须与父类一致
super().__new__(mcs, name, bases, attrs)
super().__new__(cls[, ...])
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance
a = Singleton()
b = Singleton()
print(a is b) # True
class ImmutableStr(str):
def __new__(cls, value):
# 预处理字符串
processed = value.strip().upper()
return super().__new__(cls, processed)
s = ImmutableStr(" hello ")
print(s) # "HELLO"
class ConnectionPool:
_pool = []
_max_size = 5
def __new__(cls):
if len(cls._pool) < cls._max_size:
obj = super().__new__(cls)
cls._pool.append(obj)
return obj
return cls._pool.pop(0)
conn1 = ConnectionPool()
conn2 = ConnectionPool()
class Meta(type):
def __new__(mcs, name, bases, attrs):
# 添加类属性
attrs['version'] = 1.0
return super().__new__(mcs, name, bases, attrs)
class MyClass(metaclass=Meta):
pass
print(MyClass.version) # 1.0
class SmartTuple(tuple):
def __new__(cls, iterable):
# 过滤非数字元素
filtered = (x for x in iterable if isinstance(x, (int, float)))
return super().__new__(cls, filtered)
t = SmartTuple([1, 'a', 3.14, None])
print(t) # (1, 3.14)
class Base:
def __new__(cls, *args, **kwargs):
print(f"Creating {cls.__name__}")
return super().__new__(cls)
class Child(Base):
pass
c = Child() # 输出 "Creating Child"
class A:
def __new__(cls, *args, **kwargs):
print("A's __new__")
return super().__new__(cls)
class B:
def __new__(cls, *args, **kwargs):
print("B's __new__")
return super().__new__(cls)
class C(A, B):
def __new__(cls, *args, **kwargs):
return A.__new__(cls)
obj = C() # 输出 "A's __new__"
class ErrorCase:
def __new__(cls):
# 错误:忘记返回实例
print("Creating instance") # ❌ 无返回值
def __init__(self):
print("Initializing")
e = ErrorCase() # TypeError
class DebugClass:
def __new__(cls, *args, **kwargs):
print(f"__new__ args: {args}")
instance = super().__new__(cls)
print(f"Instance ID: {id(instance)}")
return instance
def __init__(self, value):
print(f"__init__ value: {value}")
d = DebugClass(42)
class ExpensiveObject:
_cache = {}
def __new__(cls, config):
key = hash(frozenset(config.items()))
if key not in cls._cache:
instance = super().__new__(cls)
instance._init(config)
cls._cache[key] = instance
return cls._cache[key]
def __init__(self, config):
# 避免重复初始化
self.config = config
最佳实践总结:
- 优先使用
super().__new__
保证继承链正常- 修改不可变类型必须使用
__new__
- 单例模式要处理好线程安全问题
- 避免在
__new__
中做耗时操作