I’m sure that I’m missing something painfully obvious so please bear with me. However, after digging through loads of Python documentation and banging my head against several walls at once, I haven’t gotten anywhere.
In my game I have created a custom class called player, with several variables. (Including some models attached to the scene graph). I have no del method defined. There are two different players, both created in a list like this:
So, if I’m understanding you correctly, you have a party class that contains pointers to the player classes, and the player classes contain pointers to the party class? This is a common problem, and it’s often difficult to track down all of the references.
But in many cases, it doesn’t even matter. Python is reference-counted, true, and reference-counting fails to deallocate circularly linked objects like this. However, Python is also garbage-collected, and the garbage collection will usually eventually free these objects.
What, exactly, is the problem you are experiencing? You say “I try to delete self.party, but cannot get rid of it entirely,” but how do you even know whether it goes away or not, since you don’t have a del method?
In Python, you’re not supposed to have to worry about whether a particular object is deallocated or not–you simply stop using it (this is what the “del” operator actually means) and let Python worry about actually doing the deallocation when it’s ready.
There are, of course, exceptions, and it is possible to get into a situation when you have a memory leak that needs your active hand to clear up. But you have to get pretty deep into the memory management to even realize when you have a leak, and it doesn’t sound, from you’re description, that you’ve gotten to that point yet.
Party is not a class; it’s just a list with two elements, both class instances. I didn’t intend for any circular references, and I can’t see how the two class instances have references to each other.
The problem with waiting around for a GC is that the “old” models are still on screen. If I run the code multiple times (it’s for save/load), I get a screen filled with the same model.
Do I have to use del to remove all the models from the scene graph, then forget about the class instance? In other words, I can’t get Python to automatically destroy the models with the other class variables?
party = [player(foo), player(bar)]
Ah, no, the models onscreen will never be removed automatically, not even when the class referencing them destructs. Once you have attached a model to render, you have made a permanent link to that model, which persists until you explicitly break it.
It’s usually best to detach or remove the models explicitly when you know you want them to go away. You could do it in the del method, as you illustrate, but that tends to be problematic because it’s difficult to control when del gets called.
That’s a fine solution, and one which we usually employ.
Note that it’s usually not even necessary to use del. You shouldn’t confuse the Python del operator with the C++ delete operator; beginners frequently assume they are similar, but in fact they are completely different. Python’s del operator removes the local variable from the scope, but has no direct effect on the instance it refers to. But a local variable will go out of scope when the current function finishes anyway, so it’s usually unnecessary.