ActiveState Code

Recipe 52558: The Singleton Pattern implemented with Python


The following class shows how to implement the singleton pattern[1] in Python. A singleton is a class that makes sure only one instance of it is ever created. Typically such classes are used to manage resources that by their very nature can only exist once.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Singleton:
    """ A python singleton """

    class __impl:
        """ Implementation of the singleton interface """

        def spam(self):
            """ Test method, return singleton id """
            return id(self)

    # storage for the instance reference
    __instance = None

    def __init__(self):
        """ Create singleton instance """
        # Check whether we already have an instance
        if Singleton.__instance is None:
            # Create and remember instance
            Singleton.__instance = Singleton.__impl()

        # Store instance reference as the only member in the handle
        self.__dict__['_Singleton__instance'] = Singleton.__instance

    def __getattr__(self, attr):
        """ Delegate access to implementation """
        return getattr(self.__instance, attr)

    def __setattr__(self, attr, value):
        """ Delegate access to implementation """
        return setattr(self.__instance, attr, value)


# Test it
s1 = Singleton()
print id(s1), s1.spam()

s2 = Singleton()
print id(s2), s2.spam()

# Sample output, the second (inner) id is constant:
# 8172684 8176268
# 8168588 8176268

Discussion

This implementation hides the singleton interface in an inner class and creates exactly one instance of the inner class. The outer class is a handle to the inner class and delegates any requests to it. While the id() of the handle objects changes, the id() of the inner class which implements the singleton behaviour is constant.

Of course, the inner class is not REALLY hidden, like anything in Python. But you have to invest extra effort to break into the singleton.

This is related to the "Automatic delegation as an alternative to inheritance" recipe.

[1] Gamma, Helm, et al, "Design Patterns - Elements of Reusable Object-Oriented Software". Addison-Wesley, 1995, ISBN 0-201-63361-2.

Comments

  1. 1. At 1:44 p.m. on 23 apr 2001, Hrissimir Neikov said:

    RE: Singleton right behavior. all id's in the sample output must be equal!

    Try this:

    class A:
    
        # attribute known to function Singleton
    
        _instance = None
    
        def foo(self):
    
            return id(self)
    
    
    
    def Singleton(klass):
    
        if not klass._instance:
    
            klass._instance = klass()
    
        return klass._instance
    
    
    
    # subclass A
    
    class B(A):
    
        pass
    
    
    
    b = Singleton(A)
    
    c = Singleton(B)
    
    d = Singleton(A)
    
    print id(b),b.foo()
    
    print id(c),c.foo()
    
    print id(d),c.foo()
    
    
    
    # Output:
    
    7963404 7963404
    
    7963404 7963404
    
    7963404 7963404
    
  2. 2. At 6:36 p.m. on 24 jun 2001, matt kangas said:

    A simpler singleton. Phooey, both of these examples are too complicated. :-)

    class _Spam:
        def __call__(self):
            return self
    
    Spam = _Spam()
    del _Spam
    

    Alas, this isn't perfect. If for some reason you need to subclass Spam, you obviously can't. But I think this is sufficient for most people's needs.

    Since Python doesn't have any notion of class/static methods, it isn't possible to build singletons "the right way". Every workable solution will be a compromise of some sort.

  3. 3. At 2:14 a.m. on 27 jun 2001, matt kangas said:

    Obfuscated singleton. ps: Of course this is possible too...

    class Spam:
        def __call__(self):
            return self
    
    Spam = Spam()
    
  4. 4. At 4:53 p.m. on 5 aug 2001, Rowland Smith said:

    Singleton example.

    class TestSingleton :
    
        # Create a class variable that will hold a reference
        # to the single instance of TestSingleton.
    
        instance = None
    
        # Define a helper class that will override the __call___
        # method in order to provide a factory method for TestSingleton.
    
        class TestSingletonHelper :
    
            def __call__( self, *args, **kw ) :
    
                # If an instance of TestSingleton does not exist,
                # create one and assign it to TestSingleton.instance.
    
                if TestSingleton.instance is None :
                    object = TestSingleton()
                    TestSingleton.instance = object
    
                # Return TestSingleton.instance, which should contain
                # a reference to the only instance of TestSingleton
                # in the system.
    
                return TestSingleton.instance
    
        # Create a class level method that must be called to
        # get the single instance of TestSingleton.
    
        getInstance = TestSingletonHelper()
    
        # Initialize an instance of the TestSingleton class.
    
        def __init__( self ) :
    
            # Optionally, you could go a bit further to guarantee
            # that no one created more than one instance of TestSingleton:
    
            if not TestSingleton.instance == None :
                raise RuntimeError, 'Only one instance of TestSingleton is allowed!'
    
            #Continiue initialization...
    
    
    # Test this implementation of the Singleton pattern.  All of the
    # references printed out should have the same address.
    
    for i in range( 10 ) :
        print TestSingleton.getInstance()
    
    # This call should raise a RuntimeError indicating
    # that a single instance of TestSingleton already exists.
    
    TestSingleton()
    

    This singleton implementation draws from 'static method/class method'

    examples by Thomas Heller and Clark Evans.

  5. 5. At 9:19 a.m. on 16 may 2002, Sébastien Bigaret said:

    Subclassing is possible, but ugly! Inheritance is possible and can be documented as such if you use such an idiom to implement the Singleton.

    class Eggs(Spam.__class__): # The original class is still available
      def __call__(self):       # These 3 lines
        return self             # should be
    Eggs=Eggs()                 # replicated
    
  6. 6. At 9:37 a.m. on 16 may 2002, Sébastien Bigaret said:

    Small correction. This does only work if you call 'getInstance()' before the constructor ; if not, you will get a much different instances as you wish until 'getInstance()' get called:

    >>> for i in range(3):
    >>>  print '> %s'%TestSingleton()
    
    > <TestSingleton instance at 0x811f55c>
    > <TestSingleton instance at 0x812469c>
    > <TestSingleton instance at 0x811eaec>
    

    If you want to make sure that the constructor is not called more than once, 'TestSingleton.__init__' should read:

    def __init__(self):
      if not TestSingleton.instance == None :
          raise RuntimeError, 'Only one instance of TestSingleton is allowed!'
      TestSingleton.instance=self
    

    (last line added)

  7. 7. At 2:41 p.m. on 9 nov 2006, Christian Meyer said:

    Much easier solution. I found some of the previously mentioned ideas a bit too complicated. Here's my implementation:

    class _Singleton(object):
    
        def __init__(self):
            # just for the sake of information
            self.instance = "Instance at %d" % self.__hash__()
    
    
    _singleton = _Singleton()
    
    def Singleton(): return _singleton
    

    =====

    >>> from singleton import Singleton
    >>> s1 = Singleton()
    >>> s2 = Singleton()
    >>> s1.instance
    'Instance at -1226695220'
    >>> s2.instance
    'Instance at -1226695220'
    >>> s1 == s2
    True
    
  8. 8. At 1:21 p.m. on 26 nov 2007, Marc Santiago said:

    Singletons with inheritance.

    class Singleton(object):
      __single = None # the one, true Singleton
    
      def __new__(classtype, *args, **kwargs):
        # Check to see if a __single exists already for this class
        # Compare class types instead of just looking for None so
        # that subclasses will create their own __single objects
        if classtype != type(classtype.__single):
          classtype.__single = object.__new__(classtype, *args, **kwargs)
        return classtype.__single
    
      def __init__(self,name=None):
        self.name = name
    
      def display(self):
        print self.name,id(self),type(self)
    
    class Subsingleton(Singleton):
      pass
    
    if __name__ == "__main__":
      o1 = Singleton('foo')
      o1.display()
      o2 = Singleton('bar')
      o2.display()
      o3 = Subsingleton('foobar')
      o3.display()
      o4 = Subsingleton('barfoo')
      o4.display()
      print 'o1 = o2:',o1 == o2
      print 'o1 = o3:',o1 == o3
      print 'o3 = o4:',o3 == o4
      print 'o1 is a singleton?',isinstance(o1,Singleton)
      print 'o3 is a singleton?',isinstance(o3,Singleton)
      print 'o1 is a subsingleton?',isinstance(o1,Subsingleton)
      print 'o3 is a subsingleton?',isinstance(o3,Subsingleton)
    
  9. 9. At 1:07 p.m. on 13 mar 2008, Yair Chuchem said:

    good one. you should put that one as a recipe.

  10. 10. At 7:39 a.m. on 14 apr 2008, Alan Felice said:

    And what about threads? Given implementations of Singleton pattern aren't thread-safe.

    Some more stuff is needed to reach that point. Something like the

    following should be used:

    class MySingletonClass(object):
        '''Implement Pattern: SINGLETON'''
    
        __lockObj = thread.allocate_lock()  # lock object
        __instance = None  # the unique instance
    
        def __new__(cls, *args, **kargs):
            return cls.getInstance(cls, *args, **kargs)
    
        def __init__(self):
            pass
    
        def getInstance(cls, *args, **kargs):
            '''Static method to have a reference to **THE UNIQUE** instance'''
            # Critical section start
            cls.__lockObj.acquire()
            try:
                if cls.__instance is None:
                    # (Some exception may be thrown...)
                    # Initialize **the unique** instance
                    cls.__instance = object.__new__(cls, *args, **kargs)
    
                    '''Initialize object **here**, as you would do in __init__()...'''
    
            finally:
                #  Exit from critical section whatever happens
                cls.__lockObj.release()
            # Critical section end
    
            return cls.__instance
        getInstance = classmethod(getInstance)
    

Sign in to comment