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.
'''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/
'''
# - - - - - 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.
__classMap = {}
# - - - 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.
#-- 1 --
try:
return Singleton.__classMap[cls]
except KeyError:
inst = Singleton.__classMap[cls] = object.__new__(cls)
return inst