What are use cases in python 3 of writing a custom __del__
method or relying on one from stdlib1? That is, in what scenario is it reasonably safe, and can do something that's hard to do without it?
For many good reasons (1 2 3 4 5 6), the usual recommendation is to avoid __del__
and instead use context managers or perform the cleanup manually:
__del__
is not guaranteed to be called if objects are alive on intrepreter exit2.- At the point one expects the object can be destroyed, the ref count may actually be non-zero (e.g., a reference may survive through a traceback frame held onto by a calling function). This makes the destruction time far more uncertain than the mere unpredictability of
gc
implies. - Garbage collector cannot get rid of cycles if they include more than 1 object with
__del__
- The code inside
__del__
must be written super carefully:- object attributes set in
__init__
may not be present since__init__
might have raised an exception; - exceptions are ignored (only printed to
stderr
); - globals may no longer be available.
- object attributes set in
Update:
PEP 442 has made significant improvements in the behavior of __del__
. It seems though that my points 1-4 are still valid?
Update 2:
Some of the top python libraries embrace the use of __del__
in the post-PEP 442 python (i.e., python 3.4+). I guess my point 3 is no longer valid after PEP 442, and the other points are accepted as unavoidable complexity of object finalization.
1I expanded the question from just writing a custom __del__
method to include relying on __del__
from stdlib.
2It seems that __del__
is always called on interpreter exit in the more recent versions of Cpython (does anyone have a counter-example?). However, it doesn't matter for the purpose of __del__
's usablity: the docs explicitly provide no guarantee about this behavior, so one cannot rely on it (it may change in future versions, and it may be different in non-CPython interpreters).