I have a Singleton object in Python:
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
@classmethod
def destroy(cls):
del cls._instances[cls]
class MockObject(metaclass=Singleton):
def __init__(self, *args, **kwargs):
# various things
I would like to destroy the object at some point, so I wrote a classmethod in the metaclass. However, the cls
refers to the metaclass Singleton
rather than MockObject
. Is there a way to call the destroy
function with a value of MockObject
?
Instead of defining a custom method for deleting the instance reference use a WeakValueDictionary
.
Now when there are no more references of MockObject
anywhere it will be cleaned up from Singleton._instances
automatically.
from weakref import WeakValueDictionary
class Singleton(type):
_instances = WeakValueDictionary()
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
# This variable declaration is required to force a
# strong reference on the instance.
instance = super(Singleton, cls).__call__(*args, **kwargs)
cls._instances[cls] = instance
return cls._instances[cls]
class MockObject(metaclass=Singleton):
def __init__(self, *args, **kwargs):
pass
if __name__ == '__main__':
m = MockObject()
print(dict(Singleton._instances))
del m
print(dict(Singleton._instances))
Output:
{<class '__main__.MockObject'>: <__main__.MockObject object at 0x104531128>}
{}