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

A pattern using metaclasses for "blessing" classes into Singletons.

Python, 47 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
def AreYouSingle(func):
    """ Test function for verifying singularity """
    
    s1 = func()
    s2 = func()
    return (s1==s2)

class SingletonBlesserMeta(type):
    """ Type for Singleton Blesser class """

    @staticmethod
    def klsnew(cls, *args):
        if not cls.instance:
            cls.instance = object.__new__(cls)
        return cls.instance

    def my_new(cls,name,bases=(),dct={}):        
        return None

    @classmethod
    def bless(cls, *args):
        for klass in args:
            klass.instance = None
            if object in klass.__bases__:
                klass.__new__ = classmethod(cls.klsnew)

    def __init__(cls, name, bases, dct={}, *args):
        super(SingletonBlesserMeta, cls).__init__(name, bases, dct)
        cls.instance = None
        cls.__new__ = cls.my_new
        
class SingletonBless(object):
    """ Bless classes into Singletons """
    __metaclass__ = SingletonBlesserMeta

class A(object): pass
class B(object): pass
class C: pass

if __name__ == "__main__":
    # Bless the classes to make them singletons
    SingletonBless.bless(A, B, C)
    print AreYouSingle(A)
    print AreYouSingle(B)
    # Will work only if class is derived from "object"
    # so this prints False
    print AreYouSingle(C)    

Was experimenting with composing Singletons not directly at the class level, but using a "manager" class when I got this paradigm.

Put this inline in the same module that contain your class definitions, so that anyone who imports the module automatically gets them blessed as Singletons.

Can be useful to "bless" a set of classes as Singletons, without having to use inheritance.

1 comment

Michael Ihde 12 years, 6 months ago  # | flag

Being a bit pendantic, the function AreYouSingle() isn't guaranteed to be accurate. For example

class D(object):
    def __eq__(self, other):
        return

will return True for AreYouSingle even if it has not been "blessed". You should change the function to:

def AreYouSingle(func): """ Test function for verifying singularity """

s1 = func()
s2 = func()
return (id(s1)==id(s2))

So that it actually will check singularity.