views:

5383

answers:

13

There seem to be many ways to define Singletons in python. I was wondering if there is a consensus opinion on StackOverflow.

+2  A: 

Being relatively new to python I'm not sure what the most common idiom is, but the simplest thing I can think of is just using a module instead of a class. What would have been instance methods on your class become just functions in the module and any data just becomes variables in the module instead of members of the class. I suspect this is the pythonic approach to solving the type of problem that people use singletons for.

If you really want a singleton class, there's a reasonable implementation described on the first hit on google for "python singleton", specifically:

class Singleton:
    __single = None
    def __init__( self ):
        if Singleton.__single:
            raise Singleton.__single
        Singleton.__single = self

That seems to do the trick.

John
+39  A: 

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

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.

Staale
Couldn't the constructor just check if an instance has already been created and throw an exception if it has been?
Casebash
+2  A: 

Here is an example from Peter Norvig's Python IAQ How do I do the Singleton Pattern in Python? (You should use search feature of your browser to find this question, there is no direct link, sorry)

Also Bruce Eckel has another example in his book Thinking in Python (again there is no direct link to the code)

Serge
+4  A: 

@Serge: I like this quote from Norvig.

Before the Gang of Four got all academic on us, ``singleton'' (without the formal name) was just a simple idea that deserved a simple line of code, not a whole religion.

@Staale, @John: I currently use the module approach, but was wondering whether I was missing a more widely accepted approach.

Jamie
+20  A: 

A slightly different approach to implement the singleton in python is the borg pattern by Alex Martelli (google employee and python genius).

class Borg:
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state

So instead of forcing all instances to have the same identity they share state.

Peter Hoffmann
Also known as monostate. Possibly more evil than singleton.
Tom Hawtin - tackline
-1, what's the point?
hasen j
It isn't Singleton at all.
t0ster
Doesn't work with new style classes
James Emerton
+11  A: 

The module approach works well. If I absolutely need a singleton I prefer the Metaclass approach.

class Singleton(type):
    def __init__(cls, name, bases, dict):
        super(Singleton, cls).__init__(name, bases, dict)
        cls.instance = None 

    def __call__(cls,*args,**kw):
        if cls.instance is None:
            cls.instance = super(Singleton, cls).__call__(*args, **kw)
            return cls.instance

class MyClass(object):
    __metaclass__ = Singleton
Acuminate
This pattern is against the "Single Responsibility Principle" (http://c2.com/cgi/wiki?SingleResponsibilityPrinciple). See point (2) in http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx.
haridsv
+4  A: 

The one time I wrote a singleton in Python I used a class where all the member functions had the classmethod decorator.

class foo:
  x = 1

  @classmethod
  def increment(cls, y = 1):
    cls.x += y
David Locke
There should be a "def" and a ":" in there!@classmethoddef increment(cls, y = 1): cls.x += y
Adam
Quite correct. I've corrected it.
David Locke
I like this approach, but there is a minor gotcha. At least with Python 2.6, you can't make methods like `__len__` or `__getitem__` work as classmethods, so you don't have as much flexibility to customize as you would with an object. Since I often want to use a Singleton as a collection of data, that's a bit disappointing.
Dan Homerick
+2  A: 

Some people call singletons evil. I've certainly been bitten by unit-testing problems with them.

George V. Reilly
+2  A: 

There are also some interesting articles on the Google Testing blog, discussing why singleton are/may be bad and are an anti-pattern:

Singletons are Pathological Liars Where Have All the Singletons Gone? Root Cause of Singletons

FrankS
+1  A: 

I'm very unsure about this, but my project uses 'convention singletons' (not enforced singletons9, that is, if I have a class called DataController, I define this in the same module:

_data_controller = None
def GetDataController():
    global _data_controller
    if _data_controller is None:
        _data_controller = DataController()
    return _data_controller

It is not elegant, since it's a full six lines. But all my singletons use this pattern, and it's at least very explicit (which is pythonic).

kaizer.se
+2  A: 

override new method

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"
jojo
I first voted up, but realized that this is against the Single Responsibility Principle (http://c2.com/cgi/wiki?SingleResponsibilityPrinciple). See point (2) in http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx.
haridsv
A: 

i'm trying to do this, but for some reason it's not working:

class Singleton(type):
  def __new__(meta, classname, bases, classDict):
    @staticmethod
    def nonewinst(*args, **kwargs):
      raise ValueError("Can't make duplicate instance of singleton " + classname)
    @staticmethod
    def newoldnew(obj):
      return obj
    oldnew = classDict.get("__new__", newoldnew)
    @staticmethod
    def newnew(obj, *args, **kwargs):    
      o = oldnew(obj, *args, **kwargs) 
      obj.__new__ = nonewinst
      return o
    classDict["__new__"] = newnew
    return type.__new__(meta, classname, bases, classDict)

#used like this:
class SomeSingleton:
  __metaclass__ = Singleton


>>> b= A()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python25\funcs.py", line 66, in newnew
    o = oldnew(obj, *args, **kwargs)
TypeError: 'staticmethod' object is not callable
inhahe
A: 
class Singleton(object[,...]):
staticVar1 = None
staticVar2 = None
def __init__(self):
if self.__class__.staticVar1==None :
# create class instance variable for instantiation of class
# assign class instance variable values to class static variables
else :
# assign class static variable values to class instance variables