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

Why?

  • There are many recipes but nearly all cover the global singleton only.
  • I need a singleton which can handle things in a specific context (environment).

The final singleton is a combination of following two recipes:

The basic advantages:

  • Hiding the singleton code by a simple decorator
  • Flexible, because you can define fully global singletons or parameter based singletons.

Latest changes:

  • Although a function/method does not have parameters you can call it with parameters args and kwargs as you now see in the getInstance function.
  • ...
Python, 49 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
43
44
45
46
47
48
49
def singleton(theClass):
    """ decorator for a class to make a singleton out of it """
    classInstances = {}

    def getInstance(*args, **kwargs):
        """ creating or just return the one and only class instance.
            The singleton depends on the parameters used in __init__ """
        key = (theClass, args, str(kwargs))
        if key not in classInstances:
            classInstances[key] = theClass(*args, **kwargs)
        return classInstances[key]

    return getInstance

# Example

@singleton
class A:
    """ test class """
    def __init__(self, key=None, subkey=None):
        self.key    = key
        self.subkey = subkey

    def __repr__(self):
        return "A(id=%d, %s,%s)" % (id(self), self.key, self.subkey)

def tests():
    """ some basic tests """
    testCases = [ (None, None), (10, 20), (30, None), (None, 30) ]
    instances = set()
    instance1 = None
    instance2 = None

    for key, subkey in testCases:
        if key == None:
            if subkey == None: instance1, instance2 = A(), A()
            else:              instance1, instance2 = A(subkey=subkey), A(subkey=subkey)
        else:
            if subkey == None: instance1, instance2 = A(key), A(key)
            else:              instance1, instance2 = A(key, subkey=subkey), A(key, subkey=subkey)

        print("instance1: %-25s" % instance1, " instance2: %-25s" % instance2)
        assert instance1 == instance2
        assert instance1.key == key and instance1.subkey == subkey
        instances.add(instance1)

    assert len(instances) == len(testCases)

tests()
Created by Thomas Lehmann on Thu, 12 Apr 2012 (MIT)
Python recipes (4591)
Thomas Lehmann's recipes (18)

Required Modules

  • (none specified)

Other Information and Tasks