Python實現(xiàn)設計模式之單例模式詳解
設計模式簡介
設計模式是指軟件設計問題的推薦方案。設計模式一般是描述如何組織代碼和使用最佳實踐來解決常見的設計問題。需謹記一點:設計模式是高層次的方案,并不關注具體的實現(xiàn)細節(jié),比如算法和數(shù)據(jù)結構。
設計模式共分為三大類,細分為23種設計模式。
1. 創(chuàng)建型模式
2. 結構型模式
3. 行為型模式
單例
單例模式屬于創(chuàng)建型模式,是一個比較常用的一個設計模式,單例模式主要作用是讓一個類只有一個實例對象,因為在某些時候創(chuàng)建多個實例對象會浪費內存,所以目的就是為了節(jié)省內存資源。
既然是約束只能生成一個實例對象,那么就應該在實例化的過程進行修改,編寫單例的方法有很多種
使用元類 __call__
代碼示例(基于元類)
class Single(type): # 定義繼承元類type的類 def __call__(self, *args, **kwargs): # 重寫 __call__ 在類加括號調用時執(zhí)行 if not hasattr(self, 'new_obj'): # 判斷類名有沒有指定屬性 # 若沒有,則添加指定屬性,屬性值是元類__call__的返回值也就是類名 self.new_obj = super().__call__(*args, **kwargs) return self.new_obj class MyClass(metaclass=Single): def __init__(self, name): self.name = name obj1 = MyClass('X') obj2 = MyClass('W') print(obj1 is obj2) print(obj1) print(obj2)
打印結果
True
<__main__.MyClass object at 0x000001F9B382E350>
<__main__.MyClass object at 0x000001F9B382E350>
此時創(chuàng)建多個實例并不會執(zhí)行,只指向一個實例。
使用 __new__ 方法
__new__ 方法在類的實例化過程最先執(zhí)行,默認執(zhí)行 object 的 __new__ 方法,返回一個實例化對象,然后再調用 __init__ 方法,對這個對象進行初始化
class MyCls(object): # 定義繼承元類type的類 def __new__(cls, *args, **kwargs): # 重寫 __new__ 方法 if not hasattr(cls, 'new_obj'): # 如果類名沒有指定屬性 # 給類名添加屬性,屬性值是 object 的__new__方法返回值 cls.new_obj = super().__new__(cls, *args, **kwargs) return cls.new_obj # 將屬性值返回 obj = MyCls() obj1 = MyCls() print(obj is obj1) print(obj) print(obj1)
打印結果
True
<__main__.MyCls object at 0x0000024968276500>
<__main__.MyCls object at 0x0000024968276500>
第一次實例化的時候,由于判斷其沒有指定屬性,執(zhí)行添加屬性語句,屬性值是 object 的 __new__ 方法的返回值,最后返回指定屬性的值,也就是類名,而第二次實例化的時候由于已經添加了屬性,所以直接返回object 的 __new__ 方法,所以其實他們一直是同一個屬性值。
使用 @classmethod
@classmethod 會自動將類名傳入到 cls 變量中
class MyCls(object): _instance = None # 定義一個變量用于判斷 def __init__(self): pass @classmethod # 定義一個類方法 def singleton(cls): if not cls._instance: # 如果類中的指定屬性為None cls._instance = MyCls() # 設置屬性,屬性值為實例對象 return cls._instance # 將指定屬性返回 obj1 = MyCls.singleton() # 只能用類方法來獲取實例對象 obj2 = MyCls.singleton() # 只能用類方法來獲取實例對象 print(obj1) print(obj2)
打印結果
<__main__.MyCls object at 0x000002396ABB5D20>
<__main__.MyCls object at 0x000002396ABB5D20>
這個有些不同,只能用類方法來獲取實例對象。第一次調用類方法創(chuàng)建實例對象的時候在類方法中得到了一個實例對象返回值,而在第二次調用類方法創(chuàng)建對象的時候已經有了指定屬性,不滿足類方法中的判斷條,所以獲得的還是第一次實例化得到的對象。
使用裝飾器
使用裝飾器實現(xiàn)實例化并返回出來
def outer(cls): # 定義裝飾器 _instance = None # 定義變量用于判斷 def inner(*args, **kwargs): nonlocal _instance # 聲明變量 if not _instance: # 如果變量是 None _instance = cls(*args, **kwargs) # 設置屬性,屬性值為實例對象 return _instance return inner @outer # 調用裝飾器,將類名傳入到cls,也就是此時相當于 outer(MyCls) class MyCls: pass obj = MyCls() obj1 = MyCls() print(obj) print(obj1)
打印結果
<__main__.MyCls object at 0x00000165FDE05D20>
<__main__.MyCls object at 0x00000165FDE05D20>
使用模塊
模塊的方式就是在一個py文件中定義一個類,并實例化一個對象,之后在其他文件導入這一對象
到此這篇關于Python實現(xiàn)設計模式之單例模式詳解的文章就介紹到這了,更多相關Python單例模式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python人工智能實戰(zhàn)之以圖搜圖的實現(xiàn)
這篇文章主要為大家詳細介紹了如何基于vgg網絡和Keras深度學習框架實現(xiàn)以圖搜圖功能。文中的示例代碼講解詳細,感興趣的小伙伴可以學習一下2022-05-05PyTorch實現(xiàn)重寫/改寫Dataset并載入Dataloader
這篇文章主要介紹了PyTorch實現(xiàn)重寫/改寫Dataset并載入Dataloader,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07