This is an implementation of the singleton without using the __new__ class but by implementing the __call__ method in the metaclass.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class Singleton(type):
def __init__(self, *args):
type.__init__(self, *args)
self._instances = {}
def __call__(self, *args):
if not args in self._instances:
self._instances[args] = type.__call__(self, *args)
return self._instances[args]
class Test:
__metaclass__=Singleton
def __init__(self, *args): pass
ta1, ta2 = Test(), Test()
assert ta1 is ta2
tb1, tb2 = Test(5), Test(5)
assert tb1 is tb2
assert ta1 is not tb1
|
If you want a class instance to behave a certian way when it is called (i.e. obj() ) you implement its class __call__ method. If you want the class definition to behave in a certian way when called, you implement its metaclass __call__ method.
Usually (i.e. the type class) this method returns a new object, but you can do whatever you want here.
This specific implementation has a different instance per different init calls (good for immutable but changing classes, like numeric-type classes), but you can change that as you want.