什么是单例模式
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。
Python常用的单例模式写法
第一种(利用自定义类方法实现):
1 import threading 2 class Singleton(object): 3 instance_lock=threading.Lock() 4 def __init__(self,*args,**kwargs): 5 pass 6 @classmethod 7 def instance(cls,*args,**kwargs): 8 if not hasattr(cls,"_instance"): 9 with cls.instance_lock: 10 if not hasattr(Singleton,"_instance"): 11 cls._instance=Singleton(*args,**kwargs) 12 return cls._instance 13 14 def task(arg): 15 obj = Singleton.instance() 16 print(arg,obj) 17 for i in range(10): 18 t = threading.Thread(target=task,args=[i,]) 19 t.start()
第二种(利用__new__方法来实现):
1 import threading 2 class Singleton(object): 3 instance_lock=threading.Lock() 4 def __new__(cls, *args, **kwargs): 5 if not hasattr(cls,"_instance"): 6 with cls.instance_lock: 7 if not hasattr(cls,"_instance"): 8 cls._instance=object.__new__(cls,*args,**kwargs) 9 return cls._instance 10 11 obj1=Singleton() 12 obj2=Singleton() 13 print(obj1,obj2)
第三种(利用mataclass来实现):
1 import threading 2 class SingletonType(type): 3 instance=threading.Lock() 4 def __call__(cls, *args, **kwargs): 5 if not hasattr(cls,"_instance"): 6 if not hasattr(cls,"_instance"): 7 cls._instance=super(SingletonType,cls).__call__(*args,**kwargs) 8 return cls._instance 9 10 class Foo(metaclass=SingletonType): 11 def __init__(self): 12 pass 13 14 obj1=Foo() 15 obj2=Foo() 16 print(obj1,obj2)
应用
1 import pymysql 2 import threading 3 from DBUtils.PooledDB import PooledDB 4 5 class SingletonDBPool(object): 6 _instance_lock = threading.Lock() 7 8 def __init__(self): 9 self.pool = PooledDB( 10 creator=pymysql, # 使用链接数据库的模块 11 maxconnections=6, # 连接池允许的最大连接数,0和None表示不限制连接数 12 mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建 13 14 maxcached=5, # 链接池中最多闲置的链接,0和None不限制 15 maxshared=3, 16 # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。 17 blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错 18 maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制 19 setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."] 20 ping=0, 21 # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always 22 host='127.0.0.1', 23 port=3306, 24 user='root', 25 password='123', 26 database='pooldb', 27 charset='utf8' 28 ) 29 30 def __new__(cls, *args, **kwargs): 31 if not hasattr(SingletonDBPool, "_instance"): 32 with SingletonDBPool._instance_lock: 33 if not hasattr(SingletonDBPool, "_instance"): 34 SingletonDBPool._instance = object.__new__(cls, *args, **kwargs) 35 return SingletonDBPool._instance 36 37 def connect(self): 38 return self.pool.connection()