Python __del__不能作为析构函数使用?

时间:2017-01-06 23:57:51

标签: python

经过多次检查后,我确实发现了有关该主题的不一致信息。

在某些情况下,我确实发现__init__ and __del__是构造函数和析构函数的python等价物。这对于__init__来说似乎是正确的,因为我看到它在创建类时被调用;但是当程序结束时,__del__永远不会被调用。

在其他情况下,我确实发现__del__不好,你必须手动明确解除所有内容。

现在,问题是:哪个是哪个?因为使用unittest.TestCase类,当我调用__del__时,它永远不会被调用。遗憾的是,我无法使用拆卸,因为我需要在测试运行之前启动一个进程,并在完成测试后结束它

1 个答案:

答案 0 :(得分:5)

很少有SO帖子,你看到的这种行为,即例如__del__没有被调用,是一种讨论。举几个我觉得有趣的来源,包括SO和__del__文档:
What is the __del__ method, How to call it?
I don't understand this python __del__ behaviour
https://docs.python.org/3/reference/datamodel.html#object.del

我发现特别是文档中的部分:

  

注意:del x不直接调用x.__del__() - 前者将x的引用计数递减1,而后者仅在x的引用计数达到零时调用。可能阻止对象的引用计数变为零的一些常见情况包括:对象之间的循环引用(例如,双向链表或具有父指针和子指针的树数据结构);对捕获异常的函数的堆栈帧上的对象的引用(存储在sys.exc_info()2中的回溯使堆栈帧保持活动状态);或者对交互模式中引发未处理异常的堆栈帧上的对象的引用(存储在sys.last_traceback中的回溯使堆栈帧保持活动状态)。第一种情况只能通过明确打破周期来弥补;第二个可以通过释放对traceback对象不再有用的引用来解决,第三个可以通过在sys.last_traceback中存储None来解决。启用循环垃圾收集器时会检测并清除循环引用(默认情况下处于打开状态)。有关此主题的更多信息,请参阅gc模块的文档。

因此,有明显的情况可能因为对象的引用计数未达到零而未调用__del__,并且在注释中列出了可能发生这种情况的少数情况。