用__del__观察Python和PyQt中的对象破坏

时间:2013-12-20 13:38:47

标签: python garbage-collection pyqt pyside

我有一个PyQt QWidget(对象A;它只是一个pasive容器),它包含几个子窗口小部件(即有Qt'ish父子引用)。 A的子窗口小部件是从另一个对象(对象B;不一定是Qt对象)引用的,该对象向A的子节点提供数据并实际控制A的子节点的创建和结构。除了A的孩子,对象B没有其他外部参考。对象A具有对象B的引用。因此,它是循环引用的纯教科书示例。

我希望在某个时间点删除对象A和B的整个互连结构。我只需调用A.deleteLater(),建议用于Qt对象。在我看来,它工作正常并删除A和B,因为它们没有外部引用,只有相互的引用...但问题是我不确定它是否真的有效,如果它可以依赖它将在任何地方工作,如果有任何危险,如果有人将子类B作为例子。

出于调试目的,我希望使用__del__析构函数来观察A和B的正确销毁,这些析构函数只打印A was destroyed之类的内容。但后来我在文档中了解到,当__del__存在时,垃圾收集器不会收集带有循环引用的对象。这是否意味着观察破坏会影响或取消破坏?如果我是对的,这似乎就像量子力学 - 观察者的存在会影响实验的结果。

所以基本上有两个问题:

  1. deleteLater()使用正确可靠吗?以及

  2. __del__析构函数中的邮件打印是否会影响垃圾收集器?或者我可以用什么方法来观察和确认调试期间的破坏?

1 个答案:

答案 0 :(得分:0)

一种可能的方法是对对象使用weak reference,然后定期检查它是否被垃圾收集(或强制垃圾收集)。这是一个简单的例子:

>>> import weakref
>>> class Object:
...     pass
... 
>>> o = Object()
>>> r = weakref.ref(o)
>>> r()
<__main__.Object instance at 0x10e8c9e18>
>>> del o
>>> r()
<__main__.Object instance at 0x10e8c9e18>
>>> import gc
>>> gc.collect()
0
>>> r()
>>>