Completely destroying a class with models

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:

self.party = [[b]player/b, [b]player/b]

Later on, I try to delete self.party, but cannot get rid of it entirely. After reading about garbage collection, I tried using

gc.get_referrers(self.party[0])
gc.get_referrers(self.party[1])

Both of these return a list with two “main.player instance at location”. The two memory locations correspond to the two player instances.

gc.get_referrents(self.party[0]) returns the player class, and what appears to be a dict of attributes and methods. I do not see any places in the dict referring to the other player instance.

My problem is of course deleting self.party and the two player instances with it. Where am I going wrong?

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.

So, what exactly is going wrong?

David

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?

class player(bam):
  def __del__:
    self.models.removeNode()

party = [player(foo), player(bar)]
del party

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.

David

Should I create my own delete method then, and call it before using del?

Maybe I’m making this up, but I think I remember some part of the Panda manual mentioning this.

In any case, thanks for the prompt help! I appreciate it.

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.

David