问题描述
似乎有很多方法可以定义 singletons python.在堆栈溢出上是否有共识的意见?
推荐答案
我并没有真正看到需求,因为具有功能(而不是类)的模块可以很好地作为单身人士.它的所有变量都将绑定到模块,无论如何都无法重复实例化.
如果您确实希望使用类,则无法在Python中创建私人类或私人构造函数,因此除了通过使用API的惯例外,您无法防止多个实例化.我仍然只是将方法放入模块中,然后将模块视为单顿.
其他推荐答案
这是我自己的单身人士的实现.您要做的就是装饰班级;要获得单身人士,您必须使用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)
其他推荐答案
您可以覆盖这样的方法:
class Singleton(object): _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(Singleton, cls).__new__( cls, *args, **kwargs) return cls._instance if __name__ == '__main__': s1 = Singleton() s2 = Singleton() if (id(s1) == id(s2)): print "Same" else: print "Different"
问题描述
There seem to be many ways to define singletons in Python. Is there a consensus opinion on Stack Overflow?
推荐答案
I don't really see the need, as a module with functions (and not a class) would serve well as a singleton. All its variables would be bound to the module, which could not be instantiated repeatedly anyway.
If you do wish to use a class, there is no way of creating private classes or private constructors in Python, so you can't protect against multiple instantiations, other than just via convention in use of your API. I would still just put methods in a module, and consider the module as the singleton.
其他推荐答案
Here's my own implementation of singletons. All you have to do is decorate the class; to get the singleton, you then have to use the Instance method. Here's an example:
@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
And here's the code:
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)
其他推荐答案
You can override the __new__ method like this:
class Singleton(object): _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(Singleton, cls).__new__( cls, *args, **kwargs) return cls._instance if __name__ == '__main__': s1 = Singleton() s2 = Singleton() if (id(s1) == id(s2)): print "Same" else: print "Different"