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
gcimplies. - 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).
__del__in my code, and I am planning to completely abandon it. Before I do, I want to make sure I'm not missing situations where I shouldn't avoid it. Since I (and most people on SO) don't contribute to stdlib, I wanted to keep the question simpler by excluding it.__del__. You must care about cleanup enough to bother writing__del__. And yet you don't mind if the cleanup occsionally never happens or happens much later than expected (since that's the semantics of__del__). What kind of cleanup would be a good fit? Maybe freeing memory, but that's already done by gc. Maybe helping gc to free memory where it struggles?__del__call if you're close to running out of memory and most python implementations collect objects when memory is getting "sparse". So you don't care about "immediate cleanup" but only about "eventual cleanup".gccan't free memory that was allocated outside of Python (e.g. by a call tomallocfrom some shared library).