【发布时间】:2017-04-25 19:51:18
【问题描述】:
我在 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
我想在某个时候销毁对象,所以我在元类中编写了一个类方法。但是,cls 指的是元类Singleton 而不是MockObject。有没有办法以MockObject 的值调用destroy 函数?
【问题讨论】:
-
将
destroy方法放在它所属的MockObject上(或创建一个MockBase来执行此操作)。但是无论如何尝试销毁实例是没有意义的。如果在任何地方有任何其他对它的引用,它将保持活动状态。 -
为什么不在元类上定义一个
__del__方法? -
正如@kindall 指出的那样,您实际上会通过这样做引入一大堆污染。您将删除字典中的引用,但不会删除程序在其他地方的任何挥之不去的引用。现在,您最终会得到多个漂浮的单例实例。您可能想了解如何在 Python 中真正删除对象并重新考虑您的方法。
-
可能是
del Singleton._instances[cls]。您还可以使用gc模块来确保只有一个引用,否则会引发错误。 -
另外,您是否考虑过一种更简单的方法,您只需在元类上重新定义
__new__而不是__call__,它应该同时调用__new__和__init__?这基本上就是bool和NoneType在 Python 中所做的。
标签: python python-3.x metaprogramming