The lambda
in your example forms a closure. That is, it is a nested function that references objects available in its enclosing scope. Every function that creates a closure keeps a cell object for every item it needs to maintain a reference to.
In your example, the lambda
creates a closure with references to the local self
and model
variables inside the scope of the __init__
method. If you keep a reference to the lambda
somewhere, you can examine all the cell objects of its closure via its __closure__
attribute. In your example, it would display something like this:
>>> print(func.__closure__)
(<cell at 0x7f99c16c5138: MyModel object at 0x7f99bbbf0948>, <cell at 0x7f99c16c5168: MyClass object at 0x7f99bbb81390>)
If you deleted all other references to the MyModel
and MyClass
objects shown here, the ones kept by the cells would still remain. So when it comes to object cleanup, you should always explicitly disconnect all signals connected to functions that may form closures over the relevant objects.
Note that when it comes to signal/slot connections, PyQt treats wrapped C++ slots and Python instance methods differently. The reference counts of these types of callable are not increased when they are connected to signals, whereas lambdas, defined functions, partial objects and static methods are. This means that if all other references to the latter types of callable are deleted, any remaining signal connections will keep them alive. Disconnecting the signals will allow such connected callables to be garbage-collected, if necessary.
The one exception to the above is class methods. PyQt creates a special wrapper when creating connections to these, so if all other references to them are deleted, and the signal is emitted, an exception will be raised, like this:
TypeError: 'managedbuffer' object is not callable
The above should apply to PyQt5 and most versions of PyQt4 (4.3 and greater).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…