I’m writing a small application in Python 3 where objects (players) hold sets of connected objects of the same type (other players) together with data that belong to the pair of objects (the result of a played game). From time to time it is necessary to delete objects (in my example when they drop out of a tournament). If this is the case, the to-be-deleted object also must be removed from all sets of all connected objects.
So, when an object detects that it shall be deleted, it shall walk through all connected objects in its own set and call the method .remove(self)
on all connected objects. When this is done, it is ready to be destroyed.
Is it possible to have this done by simply calling del player42
? I’ve read What is the __del__ method and how do I call it? and from there (and from other resources) I learned that the method __del__
is not reliable, because it will be called only when the to-be-deleted object is garbage collected, but this can happen much later than it really should be performed.
Is there another “magic” method in Python 3 objects that will be called immediately when the del
command is performed on the object?
Advertisement
Answer
The del
command deletes a specific reference to an object, not the object itself. There may still be many other references to that object (especially in parent/child relationships) that will prevent the object from being garbage collected, and __del__
from being called. If you have time-dependent and order-specific teardown requirements, you should implement a method on your objects like destroy()
that you can call explicitly.
If you really want to use __del__
for some reason, you could make heavy use of weakrefs
to prevent hard references that would prevent garbage collection, but it would be less deterministic with the potential for race conditions and other hard to diagnose bugs.