zer0uno
zer0uno

Reputation: 8030

Garbage collector and problems with the __del__ finalizer

Surfing on the internet (here) I found that there are some problems to collect objects with __del__ method for the garbage collector.
My doubt is simple: why?

According to the documentation:

Objects that have __del__() methods and are part of a reference cycle cause the entire reference cycle to be uncollectable, including objects not necessarily in the cycle but reachable only from it. Python doesn’t collect such cycles automatically because, in general, it isn’t possible for Python to guess a safe order in which to run the __del__() methods.

Why is the __del__ method so problematic? What's the difference between an object that implements it and one which doesn't? It only destroys an instance.

Upvotes: 0

Views: 1125

Answers (1)

user4815162342
user4815162342

Reputation: 154886

__del__ doesn't destroy an instance, it is automatically destroyed by the python runtime once its reference count reaches zero. __del__ allows you to hook into that process and perform additional actions, such as freeing external resources associated with the object.

The danger is that the additional action may even resurrect the object - for example, by storing it into a global container. In that case, the destruction is effectively cancelled (until the next time the object's reference count drops to zero). It is this scenario that causes the mere presence of __del__ to exclude the object from those governed by the cycle breaker (also known as the garbage collector). If the collector invoked __del__ on all objects in the cycle, and one of them decided to resurrect the object, this would need to resurrect the whole cycle - which is impossible since __del__ method of other cycle members have already been invoked, possibly causing permanent damage to their objects (e.g. by freeing external resources, as mentioned above).

If you only need to be notified of object's destruction, use weakref.ref. If your object is associated with external resources that need freeing, implement a close method and/or a context manager interface. There is almost never a legitimate reason to use __del__.

Upvotes: 3

Related Questions