Python仅通过__init__实现单例模式的代码错误排查
Python仅通过__init__实现单例模式的代码错误排查
咱们先拆解下你这段想实现单例的代码问题出在哪哈~
首先还原你的代码和实际输出:
你的代码
class test: _instance = [] def __init__(self): if len(test._instance)!=0: print('Object instantiated') self = test._instance[0] else: test._instance.append(self) a = test() print(a) b = test() print(b)
实际输出
<__main__.test object at 0x0000023094388400> Object instantiated <__main__.test object at 0x00000230949D6700>
你预期b和a是同一个对象,但实际生成了新实例,核心问题是搞混了__init__和__new__的职责:
- Python创建对象的完整流程是:先调用
__new__方法生成一个全新的实例对象,之后才会调用__init__方法对这个实例做初始化操作。 - 你在
__init__里给self赋值test._instance[0],只是修改了__init__方法内部的局部变量指向,完全改变不了已经被__new__创建出来的那个实例。也就是说,当你执行b = test()时,Python已经通过__new__生成了新对象,__init__里的操作根本影响不了b最终指向的对象。
要正确实现单例,得从控制实例创建的入口——__new__方法下手,比如这样写:
正确实现单例的示例代码
class Test: _instance = None def __new__(cls): # 只有当_instance为空时,才创建新实例 if cls._instance is None: cls._instance = super().__new__(cls) # 始终返回同一个实例 return cls._instance a = Test() print(a) b = Test() print(b)
这样运行后,a和b会指向同一个对象,输出的内存地址完全一致。
备注:内容来源于stack exchange,提问作者karthik basavarajappa
相关产品推荐
相关产品推荐

