簡體   English   中英

Python Singleton設計模式跟蹤應用程序統計信息

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM