有没有一种简单、优雅的方式定义单例?

19 浏览
0 Comments

有没有一种简单、优雅的方式定义单例?

这个问题已经有了答案:

Python中创建单例

似乎在Python中定义单例有很多方法。在Stack Overflow上是否有共识意见?

admin 更改状态以发布 2023年5月21日
0
0 Comments

这是我自己实现的单例模式。你只需要给类加上修饰符,然后使用Instance方法就可以获得单例了。下面是一个例子:

@Singleton
class Foo:
   def __init__(self):
       print 'Foo created'
f = Foo() # Error, this isn't how you get the instance of a singleton
f = Foo.instance() # Good. Being explicit is in line with the Python Zen
g = Foo.instance() # Returns already created instance
print f is g # True

这是代码:

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)

0
0 Comments

我认为没有必要使用类来实现单例模式,因为将函数放在一个模块中已经足够实现单例。所有的变量都将绑定到该模块上,因此无论如何都无法多次实例化。

如果你确实想使用类,Python 中没有创建私有类或私有构造函数的方法,因此无法保护免受多次实例化的影响,除非通过 API 使用约定来解决。我仍然会将方法放在一个模块中,并将该模块视为单例。

0