在Python中销毁Singleton对象

use*_*188 6 python metaprogramming python-3.x

我在Python中有一个Singleton对象:

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
Run Code Online (Sandbox Code Playgroud)

我想在某个时候销毁对象,所以我在元类中编写了一个类方法.但是,cls指的是元类Singleton而不是MockObject.有没有办法destroy用值调用函数MockObject

Ash*_*ary 13

不是定义用于删除实例引用的自定义方法,而是使用a WeakValueDictionary.

现在,当没有MockObject任何地方的参考时,它将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))
Run Code Online (Sandbox Code Playgroud)

输出:

{<class '__main__.MockObject'>: <__main__.MockObject object at 0x104531128>}
{}
Run Code Online (Sandbox Code Playgroud)