Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use cases for __del__

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:

  1. __del__ is not guaranteed to be called if objects are alive on intrepreter exit2.
  2. 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.
  3. Garbage collector cannot get rid of cycles if they include more than 1 object with __del__
  4. 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.

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).

like image 692
max Avatar asked Apr 27 '17 19:04

max


People also ask

What is the use of __ del __ in Python?

The __del__() method is a known as a destructor method. It is called when an object is garbage collected which happens after all references to the object have been deleted.

Which keyword is used to invoke __ del __ method?

__del__ __del__ is a destructor method which is called as soon as all references of the object are deleted i.e when an object is garbage collected. Example: Here is the simple example of destructor. By using del keyword we deleted the all references of object 'obj', therefore destructor invoked automatically.

What is Hasattr OBJ name used for?

What is hasattr(obj,name) used for? Explanation: hasattr(obj,name) checks if an attribute exists or not and returns True or False.

When Del is called Python?

However, the documentation clearly states that: "Note: del x doesn't directly call x. __del__() — the former decrements the reference count for x by one, and the latter is only called when x's reference count reaches zero". So del is always called when you lose the last reference to the object.

How do I call the __del__ method?

Like that: obj1.del () ?. How do I call the __del__ method? __del__ is a finalizer. It is called when an object is garbage collected which happens at some point after all references to the object have been deleted. In a simple case this could be right after you say del x or, if x is a local variable, after the function ends.

What is a use case?

What are use cases? Use cases are methodologies and processes used to review and analyze systems, like software platforms. You conduct use cases to help determine, interpret and organize the requirements and features in a system and how they get used.

What are the use cases of Java?

Java Use Cases. A Cup as a Holder will hold either Tea, Coffee, or any beverage. Cup may be a good example of real-time object sorts (Tea, Coffee, etc.) holders. A Bus will carry each Man or women.

Do __Del__ methods run even at program termination?

@AndyHayden: __del__ methods might not run even at program termination, and even when they do run at termination, writing a __del__ method that works properly even while the interpreter is busy self-destructing around you requires more careful coding than many programmers apply.


1 Answers

Context managers (and try/finally blocks) are somewhat more restrictive than __del__. In general they require you to structure your code in such a way that the lifetime of the resource you need to free doesn't extend beyond a single function call at some level in the call stack, rather than, say, binding it to the lifetime of a class instance that could be destroyed at unpredictable times and places. It's usually a good thing to restrict the lifetime of resources to one scope, but there sometimes edge cases where this pattern is an awkward fit.

The only case where I've used __del__ (aside from for debugging, c.f. @MSeifert's answer) is for freeing memory allocated outside of Python by an external library. Because of the design of the library I was wrapping, it was difficult to avoid having a large number of objects that held pointers to heap-allocated memory. Using a __del__ method to free the pointers was the easiest way to do cleanup, since it would have been impractical to enclose the lifespan of each instance inside a context manager.

like image 73
ali_m Avatar answered Oct 18 '22 00:10

ali_m