4

I have a PyQt QWidget (object A; it is just a pasive container) that contains several child widgets (i.e. there are Qt'ish parent-child references). A's child widgets are referenced from another object (object B; not necessarily a Qt object) that feeds A's children with data and actually controls the creation and structure of the A's children. Apart from A's children, object B has no other outer references. Object A has a reference to object B. So, it is a pure textbook example of circular references.

I want, at some time point, delete the whole interconnected structure of objects A and B. I simply call A.deleteLater() which is recommended for Qt objects. It seems to me that it works fine and deletes A and B because they have no outer references, just the mutual ones... but the thing is that I am not very sure about if it really works, if it can be relied upon it will work everywhere and if there are any dangers if someone will subclass B for example.

For debugging purposes I wanted to observe proper destruction of A and B using __del__ destructor that would just print something like A was destroyed. But then I learned in the docs that when __del__ is present, the garbage collector will not collect such objects with circular references. Does this mean that observing the destruction will affect or cancel the destruction? If I am right this seems to be something like quantum mechanics - the existence of observer that affects the result of an experiment.

So basically there are two questions:

  1. is this use of deleteLater() correct and reliable? and

  2. Does message printing in __del__ destructor affect the garbage collector? Or what other ways I can use to observe and confirm destruction during debugging?

  • Basically, ``__del__`` in python doesn't do what you probably think it does (be the analog of C++'s ``~Destructor()``). See [here](https://docs.python.org/2/reference/datamodel.html#object.__del__) and [here](https://docs.python.org/2/library/gc.html#gc.garbage). The TL;DR, you can't rely on ``__del__`` actually being called unless you call it explicitly. – aruisdante Apr 26 '14 at 12:55
  • possible duplicate of [how to know if object gets deleted in python](http://stackoverflow.com/questions/11328219/how-to-know-if-object-gets-deleted-in-python) – aruisdante Apr 26 '14 at 12:59
  • "_But then I learned in the docs that when `__del__` is present, the garbage collector will not collect such objects with circular references_" - that's not true anymore for python3.4 with the implementation of [PEP442](http://legacy.python.org/dev/peps/pep-0442/) – mata Apr 26 '14 at 18:40
  • one could connect to `someObject.destroyed` signals to see when/if the destruction happens – mlvljr Jul 10 '14 at 19:39

1 Answers1

0

One possible approach is to use a weak reference to the object, and then periodically check to see if it's been garbage collected (or force garbage collection). Here's a simple example:

>>> 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()
>>>
Scott Maddox
  • 129
  • 7