172

I saw a class in which a __del__ method is defined. This method is used to destroy an instance of the class. However, I cannot find a place where this method is used. How is this method used? Like that: obj1.del()?.

How do I call the __del__ method?

NoDataDumpNoContribution
  • 10,591
  • 9
  • 64
  • 104
Verrtex
  • 4,317
  • 9
  • 34
  • 33
  • For readers: Check out [this video by mCoding](https://www.youtube.com/watch?v=IFjuQmlwXgU), which explains how `__del__` works and provides some alternatives to it. – InSync May 31 '23 at 15:30
  • @InSync "For **readers**: Check out this **video** by mCoding, ..." -- well, rather for those who can't read ;-) (emphasis mine) – András Aszódi Jun 05 '23 at 09:55
  • @AndrásAszódi Those who can't read might have screen *readers*. – InSync Jun 05 '23 at 14:25
  • @InSync I meant analphabets (functional or otherwise), not people with visual disabilities. But yes, you are right, there are several technologies that can help people suffering from both conditions. – András Aszódi Jun 06 '23 at 09:06

5 Answers5

240

__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. In particular, unless there are circular references, CPython (the standard Python implementation) will garbage collect immediately.*

However, this is an implementation detail of CPython. The only required property of Python garbage collection is that it happens after all references have been deleted, so this might not necessary happen right after and might not happen at all.

Even more, variables can live for a long time for many reasons, e.g. a propagating exception or module introspection can keep variable reference count greater than 0. Also, variable can be a part of cycle of references — CPython with garbage collection turned on breaks most, but not all, such cycles, and even then only periodically.

Since you have no guarantee it's executed, one should never put the code that you need to be run into __del__() — instead, this code belongs to the finally clause of a try statement or to a context manager in a with statement. However, there are valid use cases for __del__: e.g. if an object X references Y and also keeps a copy of Y reference in a global cache (cache['X -> Y'] = Y) then it would be polite for X.__del__ to also delete the cache entry.

If you know that the destructor provides (in violation of the above guideline) a required cleanup, you might want to call it directly, since there is nothing special about it as a method: x.__del__(). Obviously, you should only do so if you know it can be called twice. Or, as a last resort, you can redefine this method using

type(x).__del__ = my_safe_cleanup_method

* Reference:

CPython implementation detail: CPython currently uses a reference-counting scheme with (optional) delayed detection of cyclically linked garbage, which collects most objects as soon as they become unreachable [...] Other implementations act differently and CPython may change.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
ilya n.
  • 18,398
  • 15
  • 71
  • 89
  • Whats with `__exit__` in this context? Is it run after or before `__del__` or together? – lony May 11 '16 at 16:05
  • You could also use a class variable to tell whether it's already had `__del__` called, so you don't have to worry about a second call. – SarcasticSully Nov 14 '16 at 17:33
  • 5
    Does "might not happen at all" include when the program terminates? – Andy Hayden Nov 06 '17 at 20:47
  • 5
    @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. (CPython cleanup usually gets `__del__` methods to run at interpreter shutdown, but there are still cases where it isn't enough. Daemon threads, C-level globals, and objects with `__del__` created in another `__del__` can all lead to `__del__` methods not running.) – user2357112 Feb 15 '18 at 21:40
  • @ilyan. python [official docs](https://docs.python.org/3/reference/datamodel.html?highlight=destructor#object.__del__) explains that `__del__` method should not be called a destructor for some reason that I don't know. Do you still think that it is right to call it a destructor? –  May 23 '18 at 03:18
  • 4
    @bombs It's not a destructor for the same reason that `__init__` is not a constructor. Neither one actually creates or destroys the object. The `__init__` method initializes an object that already exists by the time it's called (which is why it doesn't return anything either). Likewise, the object still exists by the time `__del__` exits: it merely does whatever cleanup ("finalization") may be desirable before the actual destruction will take place. – Peter Hansen Feb 16 '20 at 18:51
  • I have close method written in my class and __del__ pointing to it. Is it goo practice or should i just have close method and whenver required call it? What difference __del__ method will make to class? On link - https://eli.thegreenplace.net/2009/06/12/safely-using-destructors-in-python. i found below statement which is adding more confusion. "Circular references which are garbage are detected when the option cycle detector is enabled (it’s on by default), but can only be cleaned up if there are no Python-level __del__() methods involved." – Sanjay Bhosale Nov 22 '20 at 02:44
118

I wrote up the answer for another question, though this is a more accurate question for it.

How do constructors and destructors work?

Here is a slightly opinionated answer.

Don't use __del__. This is not C++ or a language built for destructors. The __del__ method really should be gone in Python 3.x, though I'm sure someone will find a use case that makes sense. If you need to use __del__, be aware of the basic limitations per http://docs.python.org/reference/datamodel.html:

  • __del__ is called when the garbage collector happens to be collecting the objects, not when you lose the last reference to an object and not when you execute del object.
  • __del__ is responsible for calling any __del__ in a superclass, though it is not clear if this is in method resolution order (MRO) or just calling each superclass.
  • Having a __del__ means that the garbage collector gives up on detecting and cleaning any cyclic links, such as losing the last reference to a linked list. You can get a list of the objects ignored from gc.garbage. You can sometimes use weak references to avoid the cycle altogether. This gets debated now and then: see http://mail.python.org/pipermail/python-ideas/2009-October/006194.html.
  • The __del__ function can cheat, saving a reference to an object, and stopping the garbage collection.
  • Exceptions explicitly raised in __del__ are ignored.
  • __del__ complements __new__ far more than __init__. This gets confusing. See http://www.algorithm.co.il/blogs/programming/python-gotchas-1-del-is-not-the-opposite-of-init/ for an explanation and gotchas.
  • __del__ is not a "well-loved" child in Python. You will notice that sys.exit() documentation does not specify if garbage is collected before exiting, and there are lots of odd issues. Calling the __del__ on globals causes odd ordering issues, e.g., http://bugs.python.org/issue5099. Should __del__ called even if the __init__ fails? See http://mail.python.org/pipermail/python-dev/2000-March/thread.html#2423 for a long thread.

But, on the other hand:

And my pesonal reason for not liking the __del__ function.

  • Everytime someone brings up __del__ it devolves into thirty messages of confusion.
  • It breaks these items in the Zen of Python:
    • Simple is better than complicated.
    • Special cases aren't special enough to break the rules.
    • Errors should never pass silently.
    • In the face of ambiguity, refuse the temptation to guess.
    • There should be one – and preferably only one – obvious way to do it.
    • If the implementation is hard to explain, it's a bad idea.

So, find a reason not to use __del__.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
Charles Merriam
  • 19,908
  • 6
  • 73
  • 83
  • 7
    Even if the question is not exactly: why should we not use `__del__`, but how to call `__del__`, your answer is interesting. – nbro Jan 05 '15 at 20:00
  • 1
    In other news, I forgot to mention that PyPy (a faster interpreter for longer running apps) will break on __del__. – Charles Merriam Jan 26 '17 at 03:12
  • @CharlesMerriam Thank _you_ for the answer! – Tom Burrows Apr 17 '17 at 17:43
  • 4
    You have mentioned "__del__ is called when the garbage collector happens to be collecting the objects, not when you lose the last reference to an object". 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. – Tushar Vazirani Nov 12 '17 at 20:10
  • 1
    It's a bit more random than that I'm afraid. There are many reasons for not losing the last reference, and many are transient which makes reasoning and debugging difficult. And there are differences in implementations, and there are hard stops, and.. and... and... Try to recognized the ravenous bugblatter beast and use the towel to avoid it. – Charles Merriam Nov 16 '17 at 18:08
  • '__del__ is responsible for calling any __del__ in a superclass, though it is not clear if this is in method resolution order (MRO) or just calling each superclass.': probably it needs to do a call to super() and if all base classes do the same, the whole mro is covered. – Lars Nov 13 '19 at 08:54
  • Once you write a *del* operation, you are switching away automatic transmission of messages to superclasses. This means you are responsible for deciding the MRO, with the consequent grinding for special operations. This is manual, or 'driving stick'. – Charles Merriam Nov 15 '19 at 00:44
20

The __del__ method, it will be called when the object is garbage collected. Note that it isn't necessarily guaranteed to be called though. The following code by itself won't necessarily do it:

del obj

The reason being that del just decrements the reference count by one. If something else has a reference to the object, __del__ won't get called.

There are a few caveats to using __del__ though. Generally, they usually just aren't very useful. It sounds to me more like you want to use a close method or maybe a with statement.

See the python documentation on __del__ methods.

One other thing to note: __del__ methods can inhibit garbage collection if overused. In particular, a circular reference that has more than one object with a __del__ method won't get garbage collected. This is because the garbage collector doesn't know which one to call first. See the documentation on the gc module for more info.

Jason Baker
  • 192,085
  • 135
  • 376
  • 510
  • As of Python 3.4, [PEP 442](https://peps.python.org/pep-0442/) has been implemented such that objects with a \_\_del\_\_ method can be garbage collected. – Noctis Skytower Jul 28 '22 at 14:37
13

The __del__ method (note spelling!) is called when your object is finally destroyed. Technically speaking (in cPython) that is when there are no more references to your object, ie when it goes out of scope.

If you want to delete your object and thus call the __del__ method use

del obj1

which will delete the object (provided there weren't any other references to it).

I suggest you write a small class like this

class T:
    def __del__(self):
        print "deleted"

And investigate in the python interpreter, eg

>>> a = T()
>>> del a
deleted
>>> a = T()
>>> b = a
>>> del b
>>> del a
deleted
>>> def fn():
...     a = T()
...     print "exiting fn"
...
>>> fn()
exiting fn
deleted
>>>   

Note that jython and ironpython have different rules as to exactly when the object is deleted and __del__ is called. It isn't considered good practice to use __del__ though because of this and the fact that the object and its environment may be in an unknown state when it is called. It isn't absolutely guaranteed __del__ will be called either - the interpreter can exit in various ways without deleteting all objects.

Nick Craig-Wood
  • 52,955
  • 12
  • 126
  • 132
  • 1
    compared with http://stackoverflow.com/a/2452895/611007 and http://stackoverflow.com/a/1481512/611007 , `use del obj1` seems like a bad idea to rely on. – n611x007 Sep 10 '13 at 13:42
3

As mentioned earlier, the __del__ functionality is somewhat unreliable. In cases where it might seem useful, consider using the __enter__ and __exit__ methods instead. This will give a behaviour similar to the with open() as f: pass syntax used for accessing files. __enter__ is automatically called when entering the scope of with, while __exit__ is automatically called when exiting it. See this question for more details.

somoria
  • 121
  • 5