def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
@singleton
class MyClass:
...
The "Open Issues" section of that PEP says the following:
"It's exceedingly unlikely that class decorators will be in Python 2.4"
So it might not be in the current version of python.
-Farshid
Maybe to just use a module.
Bye,
bearophile
> Am I missing something here? What is the preferred pythonic way of
> implementing singleton elegantly?
Create a class and then derive from it. There are examples on the Cookbook.
--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
I would have liked to have seen Montana.
-- Capt. Vasily Borodin
>
> Am I missing something here? What is the preferred pythonic way of
> implementing singleton elegantly?
I think the most "elegant" is with a metaclass, since I feel like a
singleton is not just an ordinary type (and __init__ must be called only
once)... but, as "practicality beats purity", the most pythonic way is
probably using the __new__ method and inheritance.
Something like this:
>>> class Singleton(object):
... def __new__(cls, *args, **kwds):
... try:
... return cls._it
... except AttributeError:
... cls._it = object.__new__(cls, *args, **kwds)
... return cls._it
...
>>> class A(Singleton):
... pass
...
>>> x = A()
>>> y = A()
>>> x is y
True
But __init__ will be called once for each time you call A, even if it's
always the same instance returned. If this is a problem, you'll need
another method to use for initialization and call it only once.
--
Pedro Werneck
> class Singleton(type):
> """
> This class will allow only one instance of a type
> regardless of the initialization arguments.
> """
> def __init__(self, *args, **kwargs):
> """
> This is done when the class is defined.
> """
> type.__init__(self, *args, **kwargs)
> self._instance = None
>
> def __call__(self, *args, **kwargs):
> """
> This is called when the class is instantiated.
> """
> if not self._instance : self._instance = type.__call__(self,*args,**kwargs)
> return self._instance
>
> class namedSingleton(type):
> """
> This class will allow a different singleton per initialization
> argument list. This implementation does not take into account
> variations in the keyword args.
> """
> def __init__(self, *args, **kwargs):
> """
> This is executed when the class is first defined.
> """
> type.__init__(self, *args, **kwargs)
> self._instances = {}
>
> def __call__(self, *args, **kwargs):
> """
> This is called when the class is instantiated.
> """
> if not args in self._instances:
> self._instances[args] = type.__call__(self, *args,**kwargs )
> return self._instances[args]
You can always use the syntax the decorator replaces:
class MyClass:
...
MyClass = singleton(MyClass)
But there are better ways, and maybe you don't even need a singleton.
See the Python Cookbook.
Georg
> Am I missing something here? What is the preferred pythonic way of
> implementing singleton elegantly?
>
> Thanks for your help
> André
Hi Andre,
You might also google for
python borg pattern
As a discussion on the 'borg' design pattern might be informative.
- Pad.
Or you could always just use the __new__() method instead of __init__(),
putting all your initialization into the above except-block. If you
replace 'cls._it = ...' with 'self = cls_it = ...' you'll feel right at
home too :).
Anything 'unpythonic' (gosh how I hate that word ;)) about that, BTW?
c.u.
wildemar
> Or you could always just use the __new__() method instead of
> __init__(), putting all your initialization into the above
> except-block. If you replace 'cls._it = ...' with 'self = cls_it =
> ...' you'll feel right at home too :).
>
> Anything 'unpythonic' (gosh how I hate that word ;)) about that, BTW?
Yes. :)
You'll have to make a custom Singleton class for each subclass you want
to make a singleton, instead of just creating a custom _init method for
each one of them.
You can use the subclass __new__, but that's definitely 'unpythonic'.
--
Pedro Werneck