1、什么是单例模式:
单例模式是指一个类有且只有一个实例对象,创建一个实例对象后,再创建实例是返回上一次的对象引用。(简单的讲就是两个实例对象的ID相同,节省了内存空间)
2、单例模式的创建:
举例创建一个类,比如宇宙只有一个地球,帮助理解单例模式
class Earth: pass a=Earth() print(a) b=Earth() print(b) *****结果****** 32096552 32096496 我们可以看出两个实例内存ID不相同,该类不是一个单例模式
那么怎么能够让类只创建一个实例,而后再创建的实例是返回上一次的对象的引用呢?
我们了解到,python中,一个类创建对象实例是通过调用父类object的 __new__(cls)方法来创建对象的
我们可以通过重写 __new__(cls)方法去实现类只创建一个实例:
class Earth(object): __instance=None def __new__(cls): if cls.__instance==None:#如果__instance为空证明第一次创建实例 cls.__instance=object.__new__(cls) return cls.__instance else: #如果不是第一次创建实例,返回上一次的对象引用 return cls.__instance a=Earth() print(id(a)) b=Earth() print(b) ******结果***** 1730389200 1730389200
上面例子我们通过__new__方法创建了一个单例模式类,但是该单例类再使用多线程是会存在一定问题。我们需要加入互斥锁的方式解决该问题。
import threading class Earth(object): _instance_lock=threading.Lock() def __init__(self): pass def __new__(cls,*args,**kwargs): if not hasattr(Earth,‘_instance‘): with Earth._instance_lock: if not hasattr(Earth,‘_instance‘): Earth._instance=object.__new__(cls) return Earth._instance a=Earth() b=Earth() print(a,b) def task(arg): obj=Earth() print(obj) for i in range(10): t=threading.Thread(target=task,args=[i,]) t.start() *****结果***** <__main__.Singleton object at 0x00000000029D06A0> <__main__.Singleton object at 0x00000000029D06A0> <__main__.Singleton object at 0x00000000029D06A0> <__main__.Singleton object at 0x00000000029D06A0> <__main__.Singleton object at 0x00000000029D06A0> <__main__.Singleton object at 0x00000000029D06A0> <__main__.Singleton object at 0x00000000029D06A0> <__main__.Singleton object at 0x00000000029D06A0> <__main__.Singleton object at 0x00000000029D06A0> <__main__.Singleton object at 0x00000000029D06A0>
3、创建单例的其他方法:1、使用模块、2使用装饰器 3、使用类的方式4、基于metaclass方式
具体参考博客:https://www.cnblogs.com/huchong/p/8244279.html
原文:https://www.cnblogs.com/dushangguzhousuoli/p/11027994.html