1

I was learning about other built-in class methods in Python and came across one called __del__(). Like __repr__() and __str__(), I believed it could be overriden and decided to test it.

Here is a basic class I created:

class SomeClass:
    def __del__(self):
        print("Deleted!")

Just to confirm this code works, here is me testing it in the console:

>>> test = SomeClass()
>>> del test
Deleted!

When running in the console, I tested it with x and y variables:

>>> x = SomeClass()
>>> y = x
>>> del x # This should print "Deleted!"
>>> del y
Deleted!

Strangely, when deleting x, it never outputted anything, but when deleting y, which was assigned to be equal to the x object, it outputted "Deleted!".

I didn't stop there, though. I tested this concept again, but now with a and b variables.

>>> a = SomeClass()
>>> b = a
>>> del a
>>> b # Check if b exists
<__main__.SomeClass instance at 0x7f98a1a67fc8>
>>> del b # Like previously, with 'y', this should print "Deleted!"
>>> globals() # Well, it didn't. Let's check all our global variables to confirm
Deleted!
{'__builtins__': <module '__builtin__' (built-in)>, 'SomeClass': <class __main__.SomeClass at 0x7f98a1a5f668>, '__package__': None, '__name__': '__main__', '__doc__': None}

As you can see, calling the humble globals() method seem to print "Deleted!" then printing the globals which contains no reference of b, so it did delete it.

How comes overriding the __del__ method causes odd issues? I thought of using the method to control what happens when certain objects in a game are deleted, but now it makes me less convinced, as odd bugs may occur when I duplicate objects and delete them.

Suraj Kothari
  • 1,642
  • 13
  • 22
  • 1
    `__del__` is not a `del` hook. `__del__` is a *finalizer*. – user2357112 Jan 18 '19 at 18:28
  • 1
    `__del__` is not called because you used `del`. It is called when the *last reference* is removed. You created **two** references, `x` and `y`, so only when *both* are removed again is your object deleted from memory. – Martijn Pieters Jan 18 '19 at 18:28
  • 2
    Next, the Python interactive interpreter stores the most recently produced result in the [`_` built-in name](https://docs.python.org/3/reference/lexical_analysis.html#reserved-classes-of-identifiers). You echoed `b`, so the object was shown as a result and referenced by `_` until you produced a different result by executing `globals()` (at which point `_` is rebound to point to the global namespace dictionary, and the reference to the `SomeClass()` instance is removed and that instance is deleted because the reference count is now 0. – Martijn Pieters Jan 18 '19 at 18:32
  • It bears repeating: you are not *duplicating* objects, you are simply creating multiple references to the same object. – juanpa.arrivillaga Jan 18 '19 at 18:40

0 Answers0