我正在通过元类方法修改使用单例模式的遗留库。
继承自type
的Singleton类定义了de __call__
函数。
现在,我永远不会删除使用此库的单例对象。我在单例类中定义了__del__
方法,并且从不调用该函数。
澄清:我已经实现了一个名为Singleton
的(meta)类,它由几个类使用,使用Singleton
作为__metaclass__
。
例如,我有class A(object)
,有__metaclass__ = Singleton
。当我的程序结束时,A类有几个我想要被销毁的成员,并且A对象(唯一可以存在的对象)被销毁。
我尝试在__del__
类中定义A
方法,但它不起作用。
答案 0 :(得分:6)
__del__()
首先要说的是
无法保证在解释器退出时仍然存在的对象调用
__del__()
方法。
来自the python data model docs。因此,你不应该依赖它来整理你需要在退出时整理的状态,并且在最高级别,这就是为什么你的__del__()
可能没有被调用的原因。这是atexit
的用途。
接下来要说的是,虽然CPython使用引用计数来使其能够检测到可以在不使用垃圾收集器的情况下释放对象(导致更可预测的CPU影响和可能更高效的应用程序),但它只需要一个循环引用,一个未清除的异常,一个被遗忘的闭包或一个不同的python实现来打破,所以你应该认真地真的很难想你是否要依赖于__del__()
被调用特别要点。
通过它的声音,我猜你的单身元类(本身就是单身......)在第一次调用__call__()
时保留你的单例实例。由于元类没有被释放,因为它属于模块,它本身由sys.modules
保留,该引用在程序终止时不会消失,所以即使给出了保证提示整理所有外部对被释放的单身人士的引用,你的__del__()
不会被调用。
atexit
处理程序,以便在进程退出时进行必要的整理。__del__()
方法进行整理。例如,您可以决定整体/未来的可扩展性(例如,复数单例),您希望单例实例在不再使用时自行整理。
__del__()
方法,希望在正常的程序执行期间完成整理,你可能也想要删除atexit
处理程序。weakref
将其存放在您的元类上,这样您就不会自己保留它。