Files
2026-08-02 14:07:04 +08:00

67 lines
1.7 KiB
Python

import threading
from dataclasses import dataclass
class ParameterizedSingletonMeta(type):
"""
参数化单例元类
行为:
- 相同 (类, args, kwargs) → 同一实例
- 不同参数 → 不同实例
"""
_instances: dict = {}
_lock = threading.RLock()
def __call__(cls, *args, **kwargs):
# 1. kwargs 排序,保证顺序无关
kwargs_key = tuple(sorted(kwargs.items()))
# 2. 构造不可变的 key
key = (cls, args, kwargs_key)
# 3. 防御:确保所有参数都可 hash
try:
hash(key)
except TypeError as e:
raise ValueError(
f"{cls.__name__} 的单例参数必须全部可 hash"
) from e
with cls._lock:
if key not in cls._instances:
cls._instances[key] = super().__call__(*args, **kwargs)
else:
print(f"[HIT] 命中缓存实例: {key}")
return cls._instances[key]
@classmethod
def get_all_instances(cls):
"""调试用:返回当前已创建的所有实例"""
return list(cls._instances.values())
@dataclass
class Demo(metaclass=ParameterizedSingletonMeta):
"""
示例:参数化单例对象
"""
name: str
def __post_init__(self):
print(f"正在初始化 Demo(name={self.name})")
def __str__(self):
return f"<Demo name={self.name} id={id(self)}>"
if __name__ == "__main__":
print("=== 测试 1:相同参数 ===")
d1 = Demo(name="config_A")
d2 = Demo(name="config_A")
print(d1)
print(d2)
print("是否同一实例:", d1 is d2)
print(ParameterizedSingletonMeta.get_all_instances())