快速提问,当你说del object
时,python调用的神奇方法是什么?我知道它不是__del__
而且它不是__delete__
,所以如果有的话会被调用?如果没有调用任何内容,那么如何自定义删除对象时发生的事件?
看看下面的例子:
class SingletonError(Exception):
pass
class Singleton(type):
def __new__(metacls, name, parents, kwargs):
cls = super(Singleton, metacls).__new__(metacls, name, parents, kwargs)
cls._instance = None
return cls
def __call__(cls, *args, **kwargs):
if not cls._instance:
inst = cls.__new__(cls, *args, **kwargs)
inst.__init__(*args, **kwargs)
cls._instance = inst
return cls._instance
else:
raise SingletonError("Cannot initialize multiple singletons.")
class Logger(object, metaclass = Singleton):
def __new__(cls, *logging_args, **logging_kwargs):
self = super(Logger, cls).__new__(cls)
logging_args_dict = {'log%i' % pos : i for pos, i in enumerate(logging_args, 1)}
kwargs = dict(logging_args_dict, **logging_kwargs)
self.__dict__ = kwargs
return self
log = Logger()
当我删除日志时,我希望它再次将Logger._instance设置为None,这样您就可以重新初始化单例。我怎么能这样做?
答案 0 :(得分:2)
您可以使用weak reference代替;因为所有对Logger()
实例的引用都被清除了,所以弱引用不会阻止对象被收获。
import gc
import weakref
def __call__(cls, *args, **kwargs):
gc.collect() # optional, clear existing weak references
inst = cls._instance and cls._instance() # de-reference the weakref
if inst is None:
inst = cls.__new__(cls, *args, **kwargs)
inst.__init__(*args, **kwargs)
cls._instance = weakref.ref(inst)
return inst
else:
del inst # clear local early
raise SingletonError("Cannot initialize multiple singletons.")
cls._instance
现在是一个弱引用对象;你调用它来检索引用的对象,如果它返回None
,对象就会消失,你需要创建一个新对象。
考虑到删除不一定是即时的;一旦删除了最后一个常规引用,垃圾收集就需要运行以收集对象。
__call__
作为{{1}}中的第一行,确保在测试之前清除任何弱反应。