Python 元类Singleton对象中的析构函数

Python 元类Singleton对象中的析构函数,python,singleton,destructor,metaclass,Python,Singleton,Destructor,Metaclass,我正在通过元类方法修改一个使用单例模式的遗留库 Singleton类继承自类型,定义de\uuuu调用函数 现在,我使用这个库的单例对象永远不会被删除。我在singleton类中定义了\uuu del\uuu方法,该函数从未被调用 澄清:我已经实现了一个名为Singleton的(元)类,它被几个类使用,使用Singleton作为\uuuuuu元类 例如,我有类A(object),它有\uuuuu元类\uuuuu=Singleton。A类有几个成员,我希望在程序结束时销毁这些成员,并且A对象(唯一

我正在通过元类方法修改一个使用单例模式的遗留库

Singleton类继承自
类型
,定义de
\uuuu调用
函数

现在,我使用这个库的单例对象永远不会被删除。我在singleton类中定义了
\uuu del\uuu
方法,该函数从未被调用

澄清:我已经实现了一个名为
Singleton
的(元)类,它被几个类使用,使用
Singleton
作为
\uuuuuu元类

例如,我有
类A(object)
,它有
\uuuuu元类\uuuuu=Singleton
。A类有几个成员,我希望在程序结束时销毁这些成员,并且A对象(唯一可以存在的对象)被销毁

我尝试在
A
类中定义
\uuuu del\uuu
方法,但它不起作用。

第1点:
\uu del\uuu()
在进程退出时可能无法调用 首先要说的是

当解释器退出时,不能保证为仍然存在的对象调用
\uuu del\uu()
方法

从。因此,您不应该依赖它来整理您需要在退出时整理的状态,而在最高级别,这就是为什么您的
\uu del\uu()
可能不会被调用的原因。这就是为什么

第2点:可预测的对象生命周期是python中的一个实现细节 接下来要说的是,虽然CPython使用引用计数来检测对象是否可以在不使用垃圾收集器的情况下释放(导致更可预测的CPU影响和可能更高效的应用程序),但它只需要一个循环引用,一个未清除的异常,一个被遗忘的闭包或一个不同的python实现需要中断,因此您应该认真考虑是否要依赖于在特定点调用
\uu del\uu()

第3点:单例实现通常维护对单例实例的全局引用 听上去,我猜您的singleton元类(本身就是singleton…)在第一次调用
\uuuu call\uuuu()
时会保留您的singleton实例。由于元类属于模块而未被释放,而模块本身由
sys.modules
保留,因此在程序终止时,该引用不会消失,因此即使保证对被释放的单例的所有外部引用进行清理,您的
\u del\u()
不会被调用

你能试试吗
  • 在创建singleton实例时添加
    atexit
    处理程序,以便在流程退出时进行必要的清理
  • 如果需要,也可以在
    方法中进行整理。例如,为了整洁/将来的可扩展性(例如,使单例多样化),您可能会决定希望单例实例在不再使用时自行清理。
    
    • 如果您实现了一个
      \uu del\uu()
      方法,希望在正常的程序执行过程中进行清理,那么您可能还需要删除
      atexit
      处理程序
  • 如果你想让你的单身汉在没有人使用它的情况下被清理干净,考虑把它储存在你的元类中,这样你就不会自己保留它了。
    这可能有助于理解为什么你需要毁掉一个单身汉。你只有一个。(对吗?你说的好像你有多个单例,这让人困惑。)如果你只有一个单例,那么需要销毁它是不寻常的。你是对的。我正在编辑我的question@senderle,在某些测试场景中,创建一个在其自身之后进行清理的装置是有益的,而在生产中,只有该对象的一个实例是有意义的,并且通常不需要进行清理。