Destroying a Singleton Object in Python

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 cool method in the metaclass. However, it cls

refers to the metaclass Singleton

and not to MockObject

. Is there a way to call a function destroy

with a value MockObject

?

+3


source to share


1 answer


Instead of defining a custom method to remove the instance reference, use WeakValueDictionary

.

Now, when there are no more links to MockObject

anywhere, it will be automatically cleared of Singleton._instances

.

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>}
{}

      

+6


source







All Articles