【发布时间】:2018-11-07 01:56:11
【问题描述】:
1。 @Singleton 装饰器
我找到了一种优雅的方式来装饰 Python 类,使其成为singleton。该类只能产生一个对象。每个Instance() 调用都返回相同的对象:
class Singleton:
"""
A non-thread-safe helper class to ease implementing singletons.
This should be used as a decorator -- not a metaclass -- to the
class that should be a singleton.
The decorated class can define one `__init__` function that
takes only the `self` argument. Also, the decorated class cannot be
inherited from. Other than that, there are no restrictions that apply
to the decorated class.
To get the singleton instance, use the `Instance` method. Trying
to use `__call__` will result in a `TypeError` being raised.
"""
def __init__(self, decorated):
self._decorated = decorated
def Instance(self):
"""
Returns the singleton instance. Upon its first call, it creates a
new instance of the decorated class and calls its `__init__` method.
On all subsequent calls, the already created instance is returned.
"""
try:
return self._instance
except AttributeError:
self._instance = self._decorated()
return self._instance
def __call__(self):
raise TypeError('Singletons must be accessed through `Instance()`.')
def __instancecheck__(self, inst):
return isinstance(inst, self._decorated)
我在这里找到了代码: Is there a simple, elegant way to define singletons?
顶部的评论说:
[这是]一个非线程安全的帮助类,用于简化实现单例。
很遗憾,我没有足够的多线程经验来亲自了解“线程不安全”。
2。问题
我在多线程 Python 应用程序中使用这个 @Singleton 装饰器。我担心潜在的稳定性问题。因此:
有没有办法让这段代码完全线程安全?
如果上一个问题没有解决方案(或者它的解决方案太麻烦),我应该采取哪些预防措施来保证安全?
@Aran-Fey 指出装饰器编码错误。任何改进当然都非常感谢。
特此提供我当前的系统设置:
> Python 3.6.3
> Windows 10,64 位
【问题讨论】:
-
感谢您提供原始问题的链接;让这个答案很容易被否决......但说真的,这是一个糟糕的装饰器。
-
它似乎不起作用。
-
嗨@Aran-Fey,感谢您指出这一点。请随时对装饰器进行改进。我将不胜感激:-)
-
嗨@OlivierMelançon,到底是什么不工作?它(它 = 装饰器)似乎可以在我的系统上运行(但也许我在这里遗漏了一些东西)。但正如 Aran-Fey 刚刚指出的那样,也许应该改进装饰器 :-)
-
@K.Mulier 它确实有效......我只是觉得必须调用 Instance() 方法来获取单例很奇怪。我建议你看看this question,它展示了更整洁、更容易接受的单身人士的方式。由于它们被更广泛地使用,您会发现更容易获得有关它们的线程安全性的信息。
标签: python multithreading python-3.x singleton python-3.6