我有一个Python应用程序,它执行任务的工作流。这些任务中的每一个都可能在自己的模块中。当所有任务的列表完成后,应用程序将关闭。在它关闭之前,我想从每个任务中收集相关的统计数据。
我正在考虑使用单例模式来提供一个存储所有这些数据的地方,这样我就可以在最后检索它。每个任务将导入单例stats跟踪类,创建一个实例(该类的公共实例),并使用该实例存储任何数据。
在我的例子中,我想要一个袋子来存储来自每个任务的数据。我一直听说单身汉很坏。我想得到关于使用单例设计模式或任何其他建议的意见。
发布于 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的标准方法是使用元类;
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'这两种模式之间有一个值得注意的区别:“Borg‘’ed”类的子类与超类共享相同的状态,并且仍然可以添加更多对其实例可访问的共享状态,而Singleton类的每个子类都有自己的唯一实例,因此它自己的公共状态与超类的公共状态不相交。对于某些预期的应用程序,其中一种行为显然比另一种更合适。
https://stackoverflow.com/questions/33029875
复制相似问题