19

I do things mostly in C++, where the destructor method is really meant for destruction of an acquired resource. Recently I started with python (which is really a fun and fantastic), and I came to learn it has GC like java. Thus, there is no heavy emphasis on object ownership (construction and destruction).

As far as I've learned, the __init__() method makes more sense to me in python than it does for ruby too, but the __del__() method, do we really need to implement this built-in function in our class? Will my class lack something if I miss __del__()? The one scenario I could see __del__() useful is, if I want to log something when destroying an object. Is there anything other than this?

Ignacio Vergara Kausel
  • 5,521
  • 4
  • 31
  • 41
RaGa__M
  • 2,550
  • 1
  • 23
  • 44
  • 7
    No. You should almost never implement `__del__`. – Daniel Roseman Jun 16 '16 at 07:32
  • http://stackoverflow.com/a/2433847/2681632 – Ilja Everilä Jun 16 '16 at 07:32
  • 3
    You *almost never* want to implement `__del__`. Classes that provide a custom `__del__` have to be dealt with in a special way by the GC when dealing with cycles (because `__del__`must be called exactly once) and in some cases the GC will not be able to collect them [though from python3.4+ this has been improved quite a lot]. There are very few cases in which it is a good idea to implement it. – Bakuriu Jun 16 '16 at 07:33
  • In almost twenty years of writing Python, I never needed `__del__`. – RemcoGerlich Jun 16 '16 at 07:36
  • 1
    If you're a beginner at python you should skip the `__del__` function until way later. It's really rarely needed. – skyking Jun 16 '16 at 07:36
  • 1
    By the way, you may be interested in reading about [PEP 442: Safe Object Finalization](https://docs.python.org/3/whatsnew/3.4.html#pep-442-safe-object-finalization) – Bakuriu Jun 16 '16 at 07:38

4 Answers4

15

In the Python 3 docs the developers have now made clear that destructor is in fact not the appropriate name for the method __del__.

object.__del__(self)

Called when the instance is about to be destroyed. This is also called a finalizer or (improperly) a destructor.

Note that the OLD Python 3 docs used to suggest that 'destructor' was the proper name:

object.__del__(self)

Called when the instance is about to be destroyed. This is also called a destructor. If a base class has a __del__() method, the derived class’s __del__() method, if any, must explicitly call it to ensure proper deletion of the base class part of the instance.

From other answers but also from the Wikipedia:

In a language with an automatic garbage collection mechanism, it would be difficult to deterministically ensure the invocation of a destructor, and hence these languages are generally considered unsuitable for RAII [Resource Acquisition Is Initialization]

So you should almost never be implementing __del__, but it gives you the opportunity to do so in some (rare?) use cases

Community
  • 1
  • 1
DomTomCat
  • 8,189
  • 1
  • 49
  • 64
  • 4
    One usecase is to ensure that critical resource are cleaned up before the object is garbage-collected. I.e. in `__del__` check if resource is closed normally, and if not, do so and issue a warning. –  Jun 16 '16 at 07:56
  • Given that `__del__` is *not* a C++-style destructor, and that RAII is more or less just what Python gives you automatically, the final conclusion about when you should implement `__del__` doesn't seem to follow from what came before. – Mark Amery May 06 '18 at 22:21
6

As the other answers have already pointed out, you probably shouldn't implement __del__ in Python. If you find yourself in the situation thinking you'd really need a destructor (for example if your class wraps a resource that needs to be explicitly closed) then the Pythonic way to go is using context managers.

Florian Brucker
  • 9,621
  • 3
  • 48
  • 81
  • Context manager link was good, Does every object(including user type)implement the context manager? – RaGa__M Jun 16 '16 at 09:45
  • 1
    @Explorer_N No, you'd need to do it yourself. And they as well don't have all the same sematics. But it is easily done. – glglgl Jun 16 '16 at 09:46
  • 1
    @Explorer_N: While you usually need to implement the functionality yourself for custom classes it is often very easy using the helpers from the [`contextlib` module](https://docs.python.org/3/library/contextlib.html). – Florian Brucker Jun 16 '16 at 10:03
2

Is del really a destructor?

No, __del__ method is not a destructor, is just a normal method you can call whenever you want to perform any operation, but it is always called before the garbage collector destroys the object. Think of it like a clean or last will method.

Netwave
  • 40,134
  • 6
  • 50
  • 93
  • 1
    Will the call to __del__ happen when it has to be happen or its like what we have as finalize() in java, I heard some referring finalize() call is unpredictable – RaGa__M Jun 16 '16 at 07:39
  • @Explorer_N, it will always be called by python interpreter when the object is about to be deleted. – Netwave Jun 16 '16 at 07:40
-1

So uncommon it is that I have learned about it today (and I'm long ago into python).

Memory is deallocated, files closed, ... by the GC. But you could need to perform some task with effects outside of the class.

My use case is about implementing some sort of RAII regarding some temporal directories. I'd like it to be removed no matter what.

Instead of removing it after the processing (which, after some change, was no longer run) I've moved it to the __del__ method, and it works as expected.

This is a very specific case, where we don't really care about when the method is called, as long as it's called before leaving the program. So, use with care.

olepinto
  • 351
  • 3
  • 8
  • There is a [tempfile](https://docs.python.org/3/library/tempfile.html) module for that ([Python 2 version](https://docs.python.org/2/library/tempfile.html), for old times sake). – Cans Sep 23 '18 at 15:14