在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 timeimport threadingclass 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._instancedef 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 timeimport threadingclass 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 threadingimport 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 objclass 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 threadingclass 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._instanceclass Foo(metaclass=SingletonType): def __init__(self,arg): self.arg = argobj1 = Foo('666')obj2 = Foo('777')print(obj1,obj2)# <__main__.Foo object at 0x102240668> <__main__.Foo object at 0x102240668>