0

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?

7
  • Would this help ? stackoverflow.com/questions/1316767/…, check out import gc Commented Feb 25, 2022 at 15:45
  • Can you use with and __exit__ instead? Commented Feb 25, 2022 at 15:49
  • I learned that the method __del__ [...] will be called only when the to-be-deleted object is garbage collected - which won't happen anyway as long as your to-be-removed object is referred from other objects. Commented Feb 25, 2022 at 15:49
  • 3
    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. If you have time-dependent and order-specific teardown requirements, you should implement a method on your objects like destroy. If you reallly wanted to use __del__, 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 bugs. Commented Feb 25, 2022 at 15:49
  • 1
    It is very important to understand, del does not delete objects Commented Feb 25, 2022 at 16:14

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

I guess this is not about memory management, but about getting rid of the back references from the objects to their containers. As garbage collection can assumed to be highly non-deterministic, you should not rely on it to perform runtime-relevant operations such as removing objects from a collection.

Instead, design your system in a different, less coupled way. For example, don't keep the items in collections associated with players -- store them in separate inventories, and access them only through them. You can then just delete objects from the inventory. This is a bit similar to certain forms of database normalization.

To achieve this kind of design (updating things referred to from differnt places), games tend to use their special design patterns, for example entity component sytems.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.