python之路_flask框架_單例模式及session原理
阿新 • • 發佈:2018-02-01
sql content pytho his pri 我們 main imp dbutil
實例化補充:
一、單例模式
1、單例模式介紹
單例模式(Singleton Pattern)是一種常用的軟件設計模式,該模式的主要目的是確保某一個類只有一個實例存在。當你希望在整個系統中,某個類只能出現一個實例時,單例對象就能派上用場。常見有如下四種單例模式:
單例模式1:模塊
模塊是天然的單例模式,因為在模塊的第一次調用後會編譯成.pyc文件,在以後的調用過程中會會直接加載.pyc文件。
單例模式2:類@classmethod
(1)無法支持多線程情況:
class Singleton(object): def __init__(self): #模擬io阻塞import time time.sleep(1) @classmethod def instance(cls,*args,**kwargs): if not hasattr(Singleton,"_instance"): Singleton._instance=Singleton(*args,**kwargs) return Singleton._instance #應用 obj1=Singleton.instance() obj2=Singleton.instance() print(obj1,obj2) #<__main__.Singleton object at 0x000002C49DB6C5F8> <__main__.Singleton object at 0x000002C49DB6C5F8>
(2)支持多線程情況
import threading class Singleton(object): _instance_lock=threading.Lock() def __init__(self): import time time.sleep(1) @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(n): obj=Singleton.instance() print(n,obj) for i in range(10): t=threading.Thread(target=task,args=[i,]) t.start()
單例模式3:基於__new__
(1)不支持多線程情況
class Singleton(object): def __init__(self): pass def __new__(cls, *args, **kwargs): if not hasattr(Singleton,"_instance"): Singleton._instance=object.__new__(cls,*args,**kwargs) return Singleton._instance #應用:類實例化時會首先去執行__new__方法 obj=Singleton()
(2)支持多線程情況
import threading class Singleton(object): _instance_lock=threading.Lock() def __init__(self): import time time.sleep(1) 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 #應用:類實例化時會首先去執行__new__方法 def task(n): obj=Singleton() print(n,obj) for i in range(10): t=threading.Thread(target=task,args=[i,]) t.start()
單例模式4:基於metaclass
分析如下:
""" 1.對象是類創建,創建對象時候類的__init__方法自動執行,對象()執行類的 __call__ 方法 2.類是type創建,創建類時候type的__init__方法自動執行,類() 執行type的 __call__方法(類的__new__方法,類的__init__方法) # 第0步: 執行type的 __init__ 方法【類是type的對象】 class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): pass # 第1步: 執行type的 __call__ 方法 # 1.1 調用 Foo類(是type的對象)的 __new__方法,用於創建對象。 # 1.2 調用 Foo類(是type的對象)的 __init__方法,用於對對象初始化。 obj = Foo() # 第2步:執行Food的__call__ 方法 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,name): self.name = name
obj1 = Foo(‘name‘) obj2 = Foo(‘name‘) print(obj1,obj2)
2、單例模式應用
這裏主要針對我們上一章節講的數據庫連接池,將其與單例模式進行結合,使得任何用戶或者視圖在調用數據庫的時候,不需要反復實例化數據庫連接池對象,主要介紹如下:
import pymysql import threading from DBUtils.PooledDB import PooledDB class SingletonDBPool(object): _instance_lock = threading.Lock() def __init__(self): self.pool = PooledDB( creator=pymysql, maxconnections=6, mincached=2, maxcached=5, maxshared=3, blocking=True, maxusage=None, setsession=[], ping=0, host=‘127.0.0.1‘, port=3306, user=‘root‘, password=‘123‘, database=‘pooldb‘, charset=‘utf8‘ ) def __new__(cls, *args, **kwargs): if not hasattr(SingletonDBPool, "_instance"): with SingletonDBPool._instance_lock: if not hasattr(SingletonDBPool, "_instance"): SingletonDBPool._instance = object.__new__(cls, *args, **kwargs) return SingletonDBPool._instance def connect(self): return self.pool.connection()
上述數據庫連接池的單例模塊的引用的實例如下:
def run(): pool = SingletonDBPool() #實例化 con = pool.connect() #創建連接 # ......... con.close() #關閉,不是真正的關閉 if __name__ == ‘__main__‘: run()
二、自定義session
參考文檔:https://python-team.gitbooks.io/flask-doc/content/di-si-zhang-kuo-zhan/11-nei-zhisession-yuan-li.html
python之路_flask框架_單例模式及session原理