在flask实现单例模式的方法有多种:
这里我们列举五种,行吗?
第一种:
国际惯例:基于文件导入
第二种:
基于类的单例模式:
它又分两种: 一种加锁,一种不加锁。
不加锁的话,可以并发,但是我们的初衷是单例。
加了锁的话,可以多线程,缺陷也很明显 看代码
# 单例模式:无法支持多线程情况 # class Singleton(object): # def __init__(self): # import time # time.sleep(1) # # @classmethod # def instance(cls,*args,**kwargs): # if not hasattr(Singleton,'_instance') # # 每一个线程来,创建了一次 # Singleton._instance = Singleton(*args,**kwargs) # return Singleton._instance # # import threading # # def task(arg): # obj = Singleton.instance() # print(obj) # for i in range(4): # t = threading.Thread(target=task,args=[i,]) # t.start() """ <__main__.Singleton object at 0x10225e240> <__main__.Singleton object at 0x10227ddd8> <__main__.Singleton object at 0x10227deb8> <__main__.Singleton object at 0x1022a25c0> """ # 单例模式:支持多线程(加锁!!!!!!!) # 该方法的缺陷: 要告诉使用者,以后使用单例模式,要用Singleton.instance()!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! import time import threading class Singleton: def __init__(self): time.sleep(1) _instance_lock = threading.Lock() @classmethod def instance(cls,*args,**kwargs): if not hasattr(Singleton,'_instance'): # 加锁 with Singleton._instance_lock: if not hasattr(Singleton,'_instance'): Singleton._instance = Singleton(*args,**kwargs) return Singleton._instance def task(arg): obj = Singleton.instance() print(obj) for i in range(10): t = threading.Thread(target=task,args=[i,]) t.start() """ <__main__.Singleton object at 0x102265160> <__main__.Singleton object at 0x102265160> <__main__.Singleton object at 0x102265160> <__main__.Singleton object at 0x102265160> <__main__.Singleton object at 0x102265160> <__main__.Singleton object at 0x102265160> <__main__.Singleton object at 0x102265160> <__main__.Singleton object at 0x102265160> <__main__.Singleton object at 0x102265160> <__main__.Singleton object at 0x102265160> """
第三种:__new__方法。
########################## 基于__new__方式实现 ######################### import time import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): pass def __new__(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = object.__new__(cls, *args, **kwargs) return Singleton._instance # 单例模式,obj = Singleton() # 和基于类的单例相比,好在 这个实例化是正常实例化。 # 示例 obj1 = Singleton() obj2 = Singleton() print(obj1,obj2)
第四种:基于metaclass实现的单例
import threading import time """ class SingletonType(type): def __init__(self,*args,**kwargs): super(SingletonType, self).__init__(*args,**kwargs) def __call__(cls, *args, **kwargs): obj = cls.__new__(cls,*args,**kwargs) cls.__init__(obj,*args,**kwargs) print(obj) return obj class Foo(metaclass=SingletonType): def __init__(self,name): self.name = name def __new__(cls, *args, **kwargs): return object.__new__(cls) obj = Foo('name') print(obj) """ import threading class SingletonType(type): _instance_lock = threading.Lock() def __call__(cls, *args, **kwargs): if not hasattr(cls,'_instance'): with SingletonType._instance_lock: if not hasattr(cls,'_instance'): cls._instance = super(SingletonType, cls).__call__(*args,**kwargs) return cls._instance class Foo(metaclass=SingletonType): def __init__(self,arg): self.arg = arg obj1 = Foo('666') obj2 = Foo('777') print(obj1,obj2) # <__main__.Foo object at 0x102240668> <__main__.Foo object at 0x102240668>