如何实现基于字典的Singleton单例?已编写代码但无法运行
问题分析与解决方案
你的代码存在几个核心问题:
__new__方法调用错误:super(SingleTonNew, cls).__new__({})中,__new__的第一个参数必须是类本身,传入字典会直接触发类型错误。- 存储逻辑混淆:将单例实例的引用
_instance同时用作线程数据字典,导致实例结构混乱。 - 方法实现错配:要支持
[]字典式操作,需实现__getitem__和__setitem__方法,而非处理.属性访问的__getattr__和__setattr__。
以下是两种场景的正确实现:
场景1:线程隔离的单例字典
(匹配你代码中线程ID的设计,保证多线程下各线程数据独立)
import threading class SingleTon: # 全局单例实例存储 _instance = None def __new__(cls, *args, **kwargs): if cls._instance is None: cls._instance = super().__new__(cls) # 初始化线程隔离数据容器:键为线程ID,值为对应线程的字典 cls._instance._thread_data = {} return cls._instance def __setitem__(self, key, value): thread_id = threading.get_ident() # 为当前线程初始化字典(如果不存在) if thread_id not in self._thread_data: self._thread_data[thread_id] = {} self._thread_data[thread_id][key] = value def __getitem__(self, key): thread_id = threading.get_ident() # 从当前线程的字典中取值,无对应线程或键时抛出KeyError return self._thread_data[thread_id][key]
测试验证
# 主线程测试 singleton = SingleTon() singleton['a'] = 5 print(singleton['a']) # 输出: 5 # 多线程测试 def test_thread(): thread_id_suffix = threading.get_ident() % 1000 singleton['b'] = thread_id_suffix print(f"线程{thread_id_suffix}: singleton['b'] = {singleton['b']}") thread1 = threading.Thread(target=test_thread) thread2 = threading.Thread(target=test_thread) thread1.start() thread2.start() thread1.join() thread2.join()
场景2:全局共享的单例字典
(如果不需要线程隔离,仅需全局唯一的字典实例)
class SingleTon: _instance = None # 全局共享的字典数据 _shared_data = {} def __new__(cls, *args, **kwargs): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance def __setitem__(self, key, value): self._shared_data[key] = value def __getitem__(self, key): return self._shared_data[key]
内容的提问来源于stack exchange,提问作者Qian
相关产品推荐
相关产品推荐

