Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

There seem to be many ways to define singletons in Python. Is there a consensus opinion on Stack Overflow?

like image 947
Jamie Avatar asked Aug 28 '08 09:08

Jamie


2 Answers

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.

like image 89
Staale Avatar answered Sep 28 '22 21:09

Staale


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) 
like image 35
Paul Manta Avatar answered Sep 28 '22 23:09

Paul Manta