用__del__观察Python和PyQt中的对象破坏
问题描述
我有一个PyQt QWidget(对象A;它只是一个暂停容器),其中包含多个子小部件(即,存在类似Qt的父子引用)。A的子部件是从另一个对象(对象B;不一定是Qt对象)引用的,该对象向A的子部件提供数据,并实际控制A的子部件的创建和结构。除了A的子级,对象B没有其他外部引用。对象A引用了对象B。因此,它是循环引用的纯粹教科书示例。
我想在某个时间点删除对象A和B的整个互连结构。我只需调用A.deleteLater()
,这是为Qt对象推荐的。在我看来,它工作得很好,删除了A和B,因为它们没有外部引用,只有相互的引用……但问题是,我不太确定它是否真的有效,它是否可靠,它是否会在所有地方都适用,例如,如果有人将B级划分为B级,是否会有任何危险。
出于调试目的,我希望使用仅打印类似A was destroyed
内容的析构函数来观察A和B的正确销毁。但后来我在文档中了解到,当__del__
存在时,垃圾回收器将不会使用循环引用来收集此类对象。这是否意味着观察破坏会影响或取消破坏?如果我是对的,这似乎有点像量子力学--观察者的存在会影响实验的结果。
所以基本上有两个问题:
这种
deleteLater()
用法正确可靠吗?和__del__
析构函数中的消息打印是否会影响垃圾回收器?或者在调试期间还可以使用哪些其他方法来观察和确认破坏?
解决方案
一种可能的方法是对对象使用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()
>>>
相关文章