Is there a simple, elegant way to define singletons? [duplicate] Is there a simple, elegant way to define singletons? [duplicate] python python

Is there a simple, elegant way to define singletons? [duplicate]


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:

@Singletonclass Foo:   def __init__(self):       print 'Foo created'f = Foo() # Error, this isn't how you get the instance of a singletonf = Foo.instance() # Good. Being explicit is in line with the Python Zeng = Foo.instance() # Returns already created instanceprint 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._instanceif __name__ == '__main__':    s1 = Singleton()    s2 = Singleton()    if (id(s1) == id(s2)):        print "Same"    else:        print "Different"