Since the class is itself a singleton, it makes since to utilize it as such. The solution is to make every thing in sight a classmethod.
See
<a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52558"> ...We don't need no stinkin' singleton: Borg class</a>
<a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/102187">The Singleton Pattern implemented with Python</a>
<a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/113645">classmethod</a>
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 | def classmethod(method):
return lambda self, *args, **dict: method(self.__class__, *args, **dict)
class Singleton:
count = 0
def __init__(klass):
klass.count += 1
print klass, klass.count
__init__ = classmethod(__init__)
def __getattr__(klass, name):
return getattr(klass, name)
__getattr__ = classmethod(__getattr__)
def __setattr__(klass, name, value):
setattr(klass, name, value)
__setattr__ = classmethod(__setattr__)
c = Singleton()
d = Singleton()
c.test = 'In d?'
print 'c.test', c.test
print 'd.test', d.test
output = '''
junk.Singleton 1
junk.Singleton 2
c.test In d?
d.test In d?
'''
|
The singleton pattern has been appeared several times already, see for instance:
Prior to classmethods the programmer it seemed a bit of a hack to implement singletons. I prefer this implementation because it behaves well with inheritance (the Borg class assimilates all derived classes with its own state) and because of its clarity.
One big drawback is that the __get/setattr__ don't seem to work with the builtin classmethod. Overwriting classmethod, as above, seems to work.