Next / Previous / Contents / TCC Help System / NM Tech homepage

45. The singleton class: A classic design pattern

The movement to codify standard design patterns in software architecture stems from this seminal work:

Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides. Design patterns. Addison-Wesley, 1995, ISBN 0-201-63361-2.

The purpose of the Singleton design pattern is to make sure that a class has only instance. The Log object described in Section 3, “The singleton Log object” is an application of this pattern.

This code is in a separate file, singleton.py, and not in the logscan.py file, because it may be useful elsewhere.

A Python implementation of the Singleton pattern is given on page 84 of this work:

Martelli, Alex. Python in a nutshell. O'Reilly, 2003, 1st ed., ISBN 0-596-00188-6.

The present work is basically the same code with literate annotation.

45.1. Code prologue for singleton.py

singleton.py
'''singleton.py: A Python implementation of the Singleton pattern.

  Do not edit this file.  It is extracted automatically from the
  documentation:
    http://www.nmt.edu/tcc/help/lang/python/examples/logscan/
'''

45.2. class Singleton

singleton.py
# - - - - -   c l a s s   S i n g l e t o n

class Singleton(object):
    '''Base class for singleton objects.

      State/Invariants:
        Singleton.__classMap:
          [ a dictionary whose keys are the classes
            instantiated so far, and each related value
            is the single instance of that class ]
    '''

This class can manage any number of different derived classes. A class variable, .__classMap, is used to keep track of their instances.

singleton.py
    __classMap = {}

45.3. The .__new__() method

singleton.py
# - - -   S i n g l e t o n . _ _ n e w _ _

    def __new__ ( cls, *args, **kw ):
        '''Instance factory.

          [ if cls is a key in Singleton.__classMap ->
              return the related value
            else ->
              Singleton.__classMap[cls]  :=  a new
                  object of class cls
              return that new object ]
        '''

This method is the factory method called whenever a subclass is instantiated. The method of this name is automatically a class method, so its first argument cls is the class being instantiated.

  • If we have never seen this class before, cls will not be a key in the class variable .__classMap. We will use the object.__new__ method to create a new instance, then add that class and instance to .__classMap.

  • If we have seen this class before, the class will be a key in the .__classMap dictionary.

singleton.py
        #-- 1 --
        try:
            return Singleton.__classMap[cls]
        except KeyError:
            inst = Singleton.__classMap[cls] = object.__new__(cls)
            return inst