class SingleTonyCls(type):
_instances = {}
def __call__(cls, *args, **kwds):
if cls not in cls._instances:
print(f"{cls} does not exist! Creating new... ")
object_instance = super().__call__(*args, **kwds)
cls._instances[cls] = object_instance
print(f"[{id(object_instance)}] added to {cls} list")
# print(f"[__name__]: {__name__}") -- main file
# print(f"[cls]: {cls}") -- class name
# print(f"[__class__]: {__class__}") metaclass name
else:
print(f"{cls} exists: [{id(cls._instances[cls])}] ")
return cls._instances[cls]
1. Create Singleton Class
Singleton pattern creates a metaclass that limits the number of instance of a particular class to 1
Metaclasses allow the customisation of object instantiation (see metaclasses post)
__call__method is overriden (see: call-magic-method post)self._instanceslist: keeps track of existence of instanceid(cls._instances[cls]): allows us compare object instances
2. Create Classes: Singleton
There should only be a single instances of any class that has metaclass following the singleton pattern.
All objects have the same id.
class FooSGL(metaclass = SingleTonyCls):
pass3. Create Classes: Regular Way
There is no limit to unique instances created.
Each object should have a unique id.
class Foo():
pass4. Compare Object IDs: Singleton vs Regular Way
4.1 Create Multiple Objects: Singleton
foo_sgl_a = FooSGL()
foo_sgl_b = FooSGL()
foo_sgl_c = FooSGL()<class '__main__.FooSGL'> does not exist! Creating new...
[139808669538272] added to <class '__main__.FooSGL'> list
<class '__main__.FooSGL'> exists: [139808669538272]
<class '__main__.FooSGL'> exists: [139808669538272]
4.2 Compare Object IDs: Singleton
Each instantiation results in the returning of the first created object evidenced by the same object id
print(id(foo_sgl_a))
print(id(foo_sgl_b))
print(id(foo_sgl_c))139808669538272
139808669538272
139808669538272
4.3 Create Multiple Objects: Regular Way
foo_a = Foo()
foo_b = Foo()
foo_c = Foo()4.4 Compare Object IDs: Regular Way
Each instantiation results in a unique object id
print(id(foo_a))
print(id(foo_b))
print(id(foo_c))139808669355984
139808669358432
139808669357808