[英]Python Singleton design pattern tracking application stats
我有一個執行任務工作流程的Python應用程序。 這些任務中的每一個都可能在其自己的模塊中。 完成所有任務列表后,應用程序關閉。 在關閉之前,我想收集每個任務的相關統計信息。
我正在考慮使用單例模式來提供一個位置來存儲所有這些數據,以便最終可以進行檢索。 每個任務將導入單例統計信息跟蹤類,創建一個實例(該類的通用單個實例),並使用該實例存儲任何數據。
就我而言,我希望一個袋子存儲每個任務的數據。 我一直聽到單身人士不好。 我想獲得有關使用單例設計模式或任何其他建議的意見。
單身人士是否“壞”似乎是一個品味問題。 當然,他們有他們的位置,關於singleton主題的任何變體都應該對您有用。
自從Alex Martelli提出了聰明的ActiveState食譜Singleton以來,“ Borg模式”(色彩鮮艷且較少見的“ StatelessProxy”或“ Monostate”)就成為了Singleton的流行Python替代品。 我們不需要臭氣熏天的單例:Borg設計模式 。 它與Singleton的不同之處在於,它允許一個類的多個不同的對象共享全部的公共數據。 相比之下,單例模式可確保僅創建一個類的實例。
關於Borg vs Singleton問題的討論可以在以下stackoverflow帖子中找到: 為什么Borg模式比Python中的Singleton模式更好 ? 由於缺少_init_default_register
方法,該帖子頂部的實現可能令人困惑,該方法的目的是僅一次創建和初始化公共數據屬性。 為了進行參考和比較,下面是完整的實現(在Python 3中),這兩個實現都創建了一個數據屬性(名為data
的字典):
在Python中實現Singleton的標准方法是使用元類。
class Singleton(type):
def __init__(cls, *args, **kwargs):
cls.__instance = None
super().__init__(*args, **kwargs)
def __call__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = super().__call__(*args, **kwargs)
return cls.__instance
您可以通過提供以下元類,使統計信息跟蹤類成為單例:
class StatsTrackerSingleton(metaclass=Singleton):
def __init__(self):
self.data = {}
# ... methods to update data, summarize it, etc. ...
Borg模式更易於實現,並且由於不使用元類,因此可能更加靈活:
class StatsTrackerBorg():
__shared_data = {'data':{}}
# RHS guarantees a common dict named `data`
def __init__(self):
"""Make every instance use StatsTrackerBorg.__shared_data
for its attribute dict."""
self.__dict__ = self.__shared_data
# ... methods to update data, summarize it, etc. ...
通過上述兩種方式,您可以使用公共dict data
,也可以使用點運算符簡單地獲取和設置共享屬性。 例如,使用Borg類:
>>> a = StatsTrackerBorg()
>>> b = StatsTrackerBorg()
>>> a is b # would be True for StatsTrackerSingleton
False
>>> vars(a) is vars(b)
True
>>> vars(a)
{'data': {}}
>>> a.data['running_time'] = 10000
>>> b.bar = 10
>>> vars(a)
{'data': {'running_time': 10000}, 'bar': 10}
>>> b.foo = 'y'
>>> a.foo
'y'
兩種模式之間值得注意的區別:“博格”類的子類與超類共享相同的公共狀態,並且仍然可以為其實例添加更多共享狀態,而Singleton類的每個子類都有自己的唯一性。實例及其自身的公共狀態,與超類的狀態脫節。 對於某些預期的應用程序,其中一種行為可能顯然比另一種更為合適。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.