在python中,單例模式是一種常用的軟體設計模式,該模式的主要目的是確保某一個類別在記憶體中只能有一個實例物件;透過單例模式的方法創建的類別在目前行程中只有一個實例物件。單例模式分為:1、懶漢式,類別一載入就建立物件;2、餓漢式,用時才去建立物件。
單例模式(Singleton Pattern)是一種常用的軟體設計模式,該模式的主要目的是確保某一個類別只有一個實例存在。當你希望在整個系統中,某個類別只能出現一個實例時,單例物件就能派上用場。
例如,某個伺服器程式的設定資訊存放在一個檔案中,客戶端透過一個 AppConfig 的類別來讀取設定檔的資訊。如果在程式運行期間,有很多地方都需要使用設定檔的內容,也就是說,很多地方都需要創建AppConfig 對象的實例,這就導致系統中存在多個AppConfig 的實例對象,而這樣會嚴重浪費內存資源,尤其是在個人資料內容很多的情況下。事實上,類似 AppConfig 這樣的類,我們希望在程式運行期間只存在一個實例物件。
單例模式的要點有三個:一是某個類別只能有一個實例;二是它必須自行建立這個實例;三是它必須自行向整個系統提供這個實例。
在Python 中,我們可以用多種方法來實作單例模式:
使用模組
使用 __new__
使用裝飾器(decorator)
使用模組
其實,Python 的模組就是天然的單例模式。
因為模組在第一次導入時,會產生 .pyc 文件,當第二次導入時,就會直接載入 .pyc 文件,而不會再次執行模組程式碼。因此,我們只要把相關的函數和資料定義在一個模組中,就可以獲得一個單例物件了。
如果我們真的想要一個單例類,可以考慮這樣做:
#tests1.py class MyClass(object): def foo(self): print('MyClass.foo') my_class_obj=MyClass()
#將上面的程式碼保存在檔案 tests1.py 中,然後這樣使用:
from .tests1 import my_class_obj my_class_obj.foo()
使用__new__
為了讓類別只能出現一個實例,我們可以使用__new__ 來控制實例的建立過程,程式碼如下:
class MyClass(object): _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(MyClass, cls).__new__(cls, *args, **kwargs) return cls._instance class HerClass(MyClass): a = 1
在上面的程式碼中,我們將類別的實例和一個類別變數 _instance 關聯起來,如果 cls._instance 為None 則建立實例,否則直接傳回 cls._instance。
執行情況如下:
one = HerClass() two = HerClass() print(one == two) #True print(one is two) #True print(id(one), id(two)) #42818864 42818864
使用裝飾器
我們知道,裝飾器(decorator)可以動態地修改一個類別或函數的功能。這裡,我們也可以使用裝飾器來裝飾某個類,使其只能產生一個實例,程式碼如下:
from functools import wraps def singleton(cls): instances = {} @wraps(cls) def getinstance(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return getinstance @singleton class MyClass(object): a = 1
在上面,我們定義了一個裝飾器 singleton,它傳回了一個內部函數 getinstance ,函數會判斷某個類別是否在字典 instances 中,如果不存在,則會將 cls 作為key,cls(*args, **kw) 作為value 存到 instances 中,否則,直接返回 instances[cls]。
以上是python單例模式是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!