Welcome, guest | Sign In | My Account | Store | Cart
-1

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, 42 lines
 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

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.

13 comments

Hrissimir Neikov 13 years, 3 months ago  # | flag

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
matt kangas 13 years, 1 month ago  # | flag

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.

matt kangas 13 years ago  # | flag

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

class Spam:
    def __call__(self):
        return self

Spam = Spam()
Rowland Smith 12 years, 11 months ago  # | flag

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.

Sébastien Bigaret 12 years, 2 months ago  # | flag

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
Sébastien Bigaret 12 years, 2 months ago  # | flag

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)

Christian Meyer 7 years, 8 months ago  # | flag

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
Marc Santiago 6 years, 8 months ago  # | flag

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)
Yair Chuchem 6 years, 4 months ago  # | flag

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

Alan Felice 6 years, 3 months ago  # | flag

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)
Gary Robinson 4 years, 12 months ago  # | flag

There's a version that's been evolving for about 5 years at http://www.garyrobinson.net/2004/03/python_singleto.html. It's pretty complete and has benefitted from a fair amount of feedback and suggestions at that location. It's threadsafe and includes unit tests.

I tried to post it here, but even leaving out the unit tests, it's longer than the 3000 char limit in this comment area.

Gary Robinson 4 years, 12 months ago  # | flag

Oops, the source at the link above was accidentally an out of date version until now (without the thread-safety and some other improvements) until now. Fixed now.

Reorx 1 year, 9 months ago  # | flag

Code:

class Singleton(object):
    @classmethod
    def instance(cls, *args, **kwgs):
        if not hasattr(cls, "_instance"):
            cls._instance = cls(*args, **kwgs)
        return cls._instance

Add a comment

Sign in to comment

Created by Jürgen Hermann on Thu, 5 Apr 2001 (PSF)
Python recipes (4237)
Jürgen Hermann's recipes (14)

Required Modules

  • (none specified)

Other Information and Tasks