经过多次检查后,我确实发现了有关该主题的不一致信息。
在某些情况下,我确实发现__init__ and __del__
是构造函数和析构函数的python等价物。这对于__init__
来说似乎是正确的,因为我看到它在创建类时被调用;但是当程序结束时,__del__
永远不会被调用。
在其他情况下,我确实发现__del__
不好,你必须手动明确解除所有内容。
现在,问题是:哪个是哪个?因为使用unittest.TestCase类,当我调用__del__
时,它永远不会被调用。遗憾的是,我无法使用拆卸,因为我需要在测试运行之前启动一个进程,并在完成测试后结束它
答案 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__
,并且在注释中列出了可能发生这种情况的少数情况。