Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

singleton decorator

7 views
Skip to first unread message

Andre Meyer

unread,
Aug 7, 2006, 7:33:31 PM8/7/06
to pytho...@python.org
While looking for an elegant implementation of the singleton design pattern I came across the decorator as described in PEP318.
Unfortunately, the following does not work, because decorators only work on functions or methods, but not on classes.

def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance

@singleton
class MyClass:
...

Am I missing something here? What is the preferred pythonic way of implementing singleton elegantly?

Thanks for your help
André

Farshid Lashkari

unread,
Aug 7, 2006, 7:38:40 PM8/7/06
to
Andre Meyer wrote:
> Am I missing something here? What is the preferred pythonic way of
> implementing singleton elegantly?

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

bearoph...@lycos.com

unread,
Aug 7, 2006, 7:53:02 PM8/7/06
to
Andre Meyer:

> What is the preferred pythonic way of implementing singleton elegantly?

Maybe to just use a module.

Bye,
bearophile

Erik Max Francis

unread,
Aug 7, 2006, 8:24:30 PM8/7/06
to
Andre Meyer wrote:

> 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

Pedro Werneck

unread,
Aug 7, 2006, 8:26:16 PM8/7/06
to pytho...@python.org
On Tue, 8 Aug 2006 01:33:31 +0200
"Andre Meyer" <me...@acm.org> wrote:

>
> 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

Chaz Ginger

unread,
Aug 8, 2006, 2:58:05 AM8/8/06
to
Here is some sample code for both singleton classes and named classes
that I use:

> 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]

Georg Brandl

unread,
Aug 8, 2006, 6:46:37 AM8/8/06
to
Andre Meyer wrote:
> While looking for an elegant implementation of the singleton design
> pattern I came across the decorator as described in PEP318
> <http://www.python.org/dev/peps/pep-0318/>.

> Unfortunately, the following does not work, because decorators only work
> on functions or methods, but not on classes.
>
> def singleton(cls):
> instances = {}
> def getinstance():
> if cls not in instances:
> instances[cls] = cls()
>
> return instances[cls]
> return getinstance
>
> @singleton
> class MyClass:
> ...
>
>
> Am I missing something here? What is the preferred pythonic way of
> implementing singleton elegantly?

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

Paddy

unread,
Aug 9, 2006, 1:06:54 AM8/9/06
to

Andre Meyer wrote:

> 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.

Wildemar Wildenburger

unread,
Aug 8, 2006, 8:50:39 AM8/8/06
to pytho...@python.org
Pedro Werneck wrote:
>>>> class Singleton(object):
> ... def __new__(cls, *args, **kwds):
> ... try:
> ... return cls._it
> ... except AttributeError:
> ... cls._it = object.__new__(cls, *args, **kwds)
> ... return cls._it
>
> 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.
>

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

Pedro Werneck

unread,
Aug 9, 2006, 8:40:37 AM8/9/06
to pytho...@python.org
On Tue, 08 Aug 2006 14:50:39 +0200
Wildemar Wildenburger <wild...@freakmail.de> wrote:

> 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

0 new messages