Python 实现单例模式
程序员从来不缺对象,想 new 几个就 new 几个。

但是对象多了难免会出点问题,指不定哪天哪个对象就爆炸了。单例模式就是为了解决这个问题,无论 new 了几次,都只能存在一个对象,类似一些网站的登录,就是通过这种方式,实现只能有一个账号登录之类的功能。
首先可以简单地实现一下:
class Singleton(object):
__instance = None
def __init__(self, *args, **kwargs):
pass
@classmethod
def get_instance(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance = Singleton(*args, **kwargs)
return cls.__instance
obj1 = Singleton.get_instance()
obj2 = Singleton.get_instance()
print(obj1)
print(obj2)输出如下,可以看出两个对象 obj1 和 obj2 是同一个地址,即这个时候只有一个对象。
<__main__.Singleton object at 0x0000015F47A2CC88>
<__main__.Singleton object at 0x0000015F47A2CC88>但这种方法不是线程安全的:
import threading
import time
class Singleton(object):
__instance = None
def __init__(self, *args, **kwargs):
time.sleep(1)
@classmethod
def get_instance(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance = Singleton(*args, **kwargs)
return cls.__instance
def task():
obj = Singleton.get_instance()
print(obj)
for i in range(6):
threading.Thread(target=task).start()输出结果,出现了多个对象:
<__main__.Singleton object at 0x0000028A133F1F48>
<__main__.Singleton object at 0x0000028A134C93C8>
<__main__.Singleton object at 0x0000028A134C9288>
<__main__.Singleton object at 0x0000028A134C9148>
<__main__.Singleton object at 0x0000028A134BEFC8>
<__main__.Singleton object at 0x0000028A134C9508>而且上面这种方法只有第一次 get_instance() 的时候能给对象传递参数,总之有许多弊端。Python 提供了 __new__ 方法正好完美解决了这个问题,再加上锁,就能实现一个线程安全的单例模式:
import threading
import time
class Singleton(object):
__lock = threading.Lock()
__instance = None
def __new__(cls, *args, **kwargs):
with cls.__lock:
if not cls.__instance:
cls.__instance = super().__new__(cls)
return cls.__instance
def __init__(self, *args, **kwargs):
time.sleep(1)
def task():
obj = Singleton()
print(obj)
if __name__ == '__main__':
for i in range(6):
threading.Thread(target=task).start()输出结果:
<__main__.Singleton object at 0x000001DA4A1C0F88>
<__main__.Singleton object at 0x000001DA4A1C0F88>
<__main__.Singleton object at 0x000001DA4A1C0F88>
<__main__.Singleton object at 0x000001DA4A1C0F88>
<__main__.Singleton object at 0x000001DA4A1C0F88>
<__main__.Singleton object at 0x000001DA4A1C0F88>本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!