six_001
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
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())
|
||||
Reference in New Issue
Block a user