首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python单例设计模式跟踪应用程序统计数据

Python单例设计模式跟踪应用程序统计数据
EN

Stack Overflow用户
提问于 2015-10-09 04:21:55
回答 1查看 569关注 0票数 1

我有一个Python应用程序,它执行任务的工作流。这些任务中的每一个都可能在自己的模块中。当所有任务的列表完成后,应用程序将关闭。在它关闭之前,我想从每个任务中收集相关的统计数据。

我正在考虑使用单例模式来提供一个存储所有这些数据的地方,这样我就可以在最后检索它。每个任务将导入单例stats跟踪类,创建一个实例(该类的公共实例),并使用该实例存储任何数据。

在我的例子中,我想要一个袋子来存储来自每个任务的数据。我一直听说单身汉很坏。我想得到关于使用单例设计模式或任何其他建议的意见。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-09 06:43:52

单身人士是否“坏”似乎是一个品味问题。当然,他们有自己的位置,任何关于独生子女主题的变体都应该适合你。

"Borg模式“(颜色较少,更不常见,"StatelessProxy”或"Monostate")可能是继alternative的聪明的ActiveState食谱辛格尔顿?我们不需要一个人: Borg设计模式之后流行的Python替代方案。它与Singleton不同,它允许一个类的多个不同的对象,所有这些对象都共享公共数据。相反,Singleton模式确保只创建类的一个实例。

关于Borg与Singleton问题的讨论可以在以下堆栈溢出文章中找到:为什么Borg模式比Python中的Singleton模式更好。文章顶部的实现可能令人费解,因为缺少的_init_default_register方法只用于创建和初始化公共数据属性一次。为了进行参考和比较,下面是完整的实现(在Python3中),这两个实现都创建了一个数据属性(名为data的dict ):

在Python中实现Singleton的标准方法是使用元类;

代码语言:javascript
复制
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

通过提供这个元类,可以使统计跟踪类成为一个单独的类:

代码语言:javascript
复制
class StatsTrackerSingleton(metaclass=Singleton):
    def __init__(self):
        self.data = {}

    # ... methods to update data, summarize it, etc. ...

Borg模式更易于实现,而且由于它不使用元类,因此可能更灵活:

代码语言:javascript
复制
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类:

代码语言:javascript
复制
>>> 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'

这两种模式之间有一个值得注意的区别:“Borg‘’ed”类的子类与超类共享相同的状态,并且仍然可以添加更多对其实例可访问的共享状态,而Singleton类的每个子类都有自己的唯一实例,因此它自己的公共状态与超类的公共状态不相交。对于某些预期的应用程序,其中一种行为显然比另一种更合适。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33029875

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档