如何调试未被调用的 __del__()

3 投票
3 回答
1072 浏览
提问于 2025-04-17 00:39

我用 __del__() 这个方法来写一个警告日志,以防对象在内部状态不对的时候被删除(请不要对此太生气)。

我试着测试这个方法,但虽然我在测试中使用了 del my_object,但是 __del__() 似乎没有被调用。

__del__() 的参考文档 提到有三种情况可能导致这个方法不被调用,但没有给出调试的线索。

那么... 我该如何调试这个问题呢?

3 个回答

3

你可以试着强制 垃圾回收器 去回收那些对象。如果你想知道哪些对象还在引用你的对象,可能是它们让你的对象无法被垃圾回收,可以试试 gc.get_referrersgc.get_referents 这两个工具。

4

你可以把所有可疑对象之间的引用都改成弱引用,然后观察你提供给weakref.ref的回调函数的输出。

4

如果你在直接使用 del myObject 时发现 __del__ 没有被调用,那说明还有其他地方在引用着 myObject。很可能你把它放进了一个列表、字典或者集合里(或者可能是某种缓存),这些操作并不会复制这个对象,而只是保存了对原对象的另一个引用。

myObject = MyObjectClassWith__del__()
del myObject

即使你这样做:

也不一定会调用 __del__,如果这个类的 __init__ 方法或者 __new__ 方法把新实例保存到了某个类级别的缓存或结构中。

总之:要检查一下是否还有其他引用,可以通过查看你的代码,或者使用其他答案中提到的 weakref 或 gc 方法来帮助你。

撰写回答