Django 知识补漏单例模式
生活随笔
收集整理的這篇文章主要介紹了
Django 知识补漏单例模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
單例模式:(說白了就是)創建一個類的實例。在 Python 中,我們可以用多種方法來實現單例模式:
1、文件導入的形式(常用)
s1.pyclass Foo(object):def test(self):print("123")v = Foo() #v是Foo的實例s2.py復制代碼 from s1 import v as v1 print(v1,id(v1)) from s1 import v as v2 print(v1,id(v2)) # 文件加載的時候,第一次導入后,會生成 .pyc 文件,當第二次導入時,就會直接加載 .pyc 文件,再次導入時不會再重新加載。 # 兩個的內存地址是一樣的2、基于類實現的單例模式
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' # ======================單例模式:無法支持多線程情況===============class Singleton(object):def __init__(self):import timetime.sleep(1)@classmethoddef instance(cls, *args, **kwargs):if not hasattr(Singleton, "_instance"):Singleton._instance = Singleton(*args, **kwargs)return Singleton._instanceimport threadingdef task(arg):obj = Singleton.instance()print(obj)for i in range(10):t = threading.Thread(target=task,args=[i,])t.start()# ====================單例模式:支持多線程情況================、import time import threading class Singleton(object):_instance_lock = threading.Lock()def __init__(self):time.sleep(1)@classmethoddef 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() time.sleep(20) obj = Singleton.instance() print(obj) # 使用先說明,以后用單例模式,obj = Singleton.instance() # 示例: # obj1 = Singleton.instance() # obj2 = Singleton.instance() # print(obj1,obj2) # 錯誤示例 # obj1 = Singleton() # obj2 = Singleton() # print(obj1,obj2)3、基于__new__實現的單例模式(最常用 推薦使用,方便)
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' # =============單線程下執行=============== import threading class Singleton(object):_instance_lock = threading.Lock()def __init__(self):passdef __new__(cls, *args, **kwargs):if not hasattr(Singleton, "_instance"):with Singleton._instance_lock:if not hasattr(Singleton, "_instance"):# 類加括號就回去執行__new__方法,__new__方法會創建一個類實例:Singleton()Singleton._instance = object.__new__(cls, *args, **kwargs) # 繼承object類的__new__方法,類去調用方法,說明是函數,要手動傳clsreturn Singleton._instance #obj1#類加括號就會先去執行__new__方法,在執行__init__方法 # obj1 = Singleton() # obj2 = Singleton() # print(obj1,obj2)# ===========多線程執行單利============ def task(arg):obj = Singleton()print(obj)for i in range(10):t = threading.Thread(target=task,args=[i,])t.start() # 使用先說明,以后用單例模式,obj = Singleton() # 示例 # obj1 = Singleton() # obj2 = Singleton() # print(obj1,obj2)4、基于metaclass(元類)實現的單例模式
""" ''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' 1.對象是類創建,創建對象時候類的__init__方法自動執行,對象()執行類的 __call__ 方法 2.類是type創建,創建類時候type的__init__方法自動執行,類() 執行type的 __call__方法(類的__new__方法,類的__init__方法)# 第0步: 執行type的 __init__ 方法【類是type的對象】 class Foo:def __init__(self):passdef __call__(self, *args, **kwargs):pass# 第1步: 執行type的 __call__ 方法 # 1.1 調用 Foo類(是type的對象)的 __new__方法,用于創建對象。 # 1.2 調用 Foo類(是type的對象)的 __init__方法,用于對對象初始化。 obj = Foo() # 第2步:執行Foo的 __call__ 方法 obj() """# ===========類的執行流程================ class SingletonType(type):def __init__(self,*args,**kwargs):print(self) #會不會打印? #<class '__main__.Foo'>super(SingletonType,self).__init__(*args,**kwargs)def __call__(cls, *args, **kwargs): #cls = Fooobj = cls.__new__(cls, *args, **kwargs)obj.__init__(*args, **kwargs)return objclass Foo(metaclass=SingletonType):def __init__(self,name):self.name = namedef __new__(cls, *args, **kwargs):return object.__new__(cls, *args, **kwargs) '''1、對象是類創建的,創建對象時類的__init__方法會自動執行,對象()執行類的__call__方法2、類是type創建的,創建類時候type類的__init__方法會自動執行,類()會先執行type的__call__方法(調用類的__new__,__init__方法)Foo 這個類是由SingletonType這個類創建的 ''' obj = Foo("hiayan")# ============第三種方式實現單例模式================= 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,name):self.name = nameobj1 = Foo('name') obj2 = Foo('name') print(obj1,obj2)簡單總結
單例只有一個實例
靜態方法、靜態字段
所有封裝數據都一樣時用單例模式
靜態方法:無法訪問類屬性、實例屬性,相當于一個相對獨立的方法,跟類其實沒什么關系,換個角度來講,其實就是放在一個類的作用域里的函數而已。
類成員方法:可以訪問類屬性,無法訪問實例屬性。在類里是類變量,在實例中又是實例變量,所以容易混淆。
總結
以上是生活随笔為你收集整理的Django 知识补漏单例模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Django 函数和方法的区别
- 下一篇: Django基础知识MTV