Python Singleton

Sometimes a Singleton comes in handy. In this case will be used to provide a directory of fonts. Loading fonts uses resources and should done only once. The Singleton will hold references to all fonts already loaded and will load a requested font, if not available yet.

The second example in PEP 318 shows an approach using a decorator.

def singleton(cls):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance</code>

@singleton
class MyClass:
    ...

This works, but does not allow parameters to be passed to __init__. Modifying the decorator a bit allows passing of parameters, in this case even updating the existing Singleton.

def singleton(cls):
    instances = {}
    def getinstance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls()
        instance[cls].__init__(*args, **kw)
        return instances[cls]
    return getinstance</code>

@singleton
class OnlyOne:
    store = []
    def __init__(self, value=None):
        if value:
            self.append(value)
    def append(self, value):
        self.store.append(value)

if __name__ == '__main__':
    obj1 = OnlyOne(1)
    print obj1.store

    obj2 = OnlyOne(2)
    print obj2.store

    print obj1.store

This results in:

[1]
[1, 2]
[1, 2]

Exactly the result I am looking for. The actual code for the font directory will use a Dict, but that is just a minor modification.

Leave a comment