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