python 使用裝飾器實現單例模式
阿新 • • 發佈:2018-11-12
1、裝飾器
python中一切皆物件,同樣函式也是一個物件。函式物件有一個__name__屬性,可以檢視函式的名字。
def demo():
print("xxx")
print(demo.__name__)
output:
demo
假設我們要增強函式demod的功能,比如在函式執行前自動列印日誌,但又不希望改變demo()函式的定義,此時就用到了裝飾器。
這種在程式碼執行期間動態增加功能的方式,稱為裝飾器(decorator)。Python的decorator可以用函式實現,也可以用類實現。
def log(func): def wrapper(*args, **kw): print 'call %s():' % func.__name__ return func(*args, **kw) return wrapper @log def demo(): print("xxx") demo() output: call demo(): xxx
2、單例模式
單例模式(Singleton Pattern)是一種常用的軟體設計模式,該模式的主要目的是確保某個類只有一個例項存在。如某個程式的配置檔案,程式可能通過一個Settings的類來讀取配置檔案的資訊。如果在程式執行期間有很多地方需要用到配置檔案的內容,也就是很多地方需要建立Settings的例項,這就導致刺痛中存在多個Settings的例項物件,這樣會嚴重浪費記憶體資源。類似於這種情況,我們希望程式執行期間只存在一個例項物件。
3、裝飾器來實現單例模式:
from functools import wraps def Singleton(cls): _instance = {} @wraps(cls) def _singleton(*args, **kargs): if cls not in _instance: _instance[cls] = cls(*args, **kargs) return _instance[cls] return _singleton @Singleton class Settings(): """Docstring""" def __init__(self): self.a = "xxx" self.b = "xxx" settings = Settings() print(settings.a) print(Settings.__name__) print(Settings.__doc__) output: xxx Settings Docstring
程式碼中@wraps的作用:Python裝飾器(decorator)在實現的時候,被裝飾後的函式其實已經是另外一個函數了(函式名等函式屬性會發生改變),為了不影響,Python的functools包中提供了一個叫wraps的decorator來消除這樣的副作用。寫一個decorator的時候,最好在實現之前加上functools的wrap,它能保留原有函式的名稱和docstring。