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"" 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())