python – Is there a simple, elegant way to define singletons?
python – Is there a simple, elegant way to define singletons?
I dont 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 cant 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.
Heres 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. Heres an example:
@Singleton
class Foo:
def __init__(self):
print Foo created
f = Foo() # Error, this isnt 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 heres 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)
python – Is there a simple, elegant way to define singletons?
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