Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python __del__ does not work as destructor? [duplicate]

Tags:

python

After checking numerous times, I did find inconsistent info about the topic.

In some case, I did find that __init__ and __del__ are the python equivalent of constructors and destructors. This seems to be true for __init__, since I see it called when the class is created; but __del__ is never called, when the program end.

In other cases, I did find that __del__ is bad, and you have to explicitly deallocate everything by hand.

Now, the issue is: which is which? Because using a unittest.TestCase class, when I call __del__ it never get called. Sadly I can't use tear down because I need to start a process before the tests run, and end it once I am done with the tests


1 Answers

There are few SO posts in which this kind of behavior that you see, namely for example that __del__ doesn't gets called, is kind of discussed. To name a few sources that I found interesting, both SO and the __del__ documentation:
What is the __del__ method, How to call it?
I don't understand this python __del__ behaviour
https://docs.python.org/3/reference/datamodel.html#object.del

I found especially illuminating the section from the documentation:

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. Some common situations that may prevent the reference count of an object from going to zero include: circular references between objects (e.g., a doubly-linked list or a tree data structure with parent and child pointers); a reference to the object on the stack frame of a function that caught an exception (the traceback stored in sys.exc_info()2 keeps the stack frame alive); or a reference to the object on the stack frame that raised an unhandled exception in interactive mode (the traceback stored in sys.last_traceback keeps the stack frame alive). The first situation can only be remedied by explicitly breaking the cycles; the second can be resolved by freeing the reference to the traceback object when it is no longer useful, and the third can be resolved by storing None in sys.last_traceback. Circular references which are garbage are detected and cleaned up when the cyclic garbage collector is enabled (it’s on by default). Refer to the documentation for the gc module for more information about this topic.

So there are clearly cases in which __del__ might not be called because the reference count of an object hasn't reached zero and in the note few cases are listed in which this situation might happen.

like image 68
fedepad Avatar answered Sep 07 '26 03:09

fedepad