Tubez
28-03-2007 00:02:48
I have noticed that some example programs attempt to mirror the C++ way of dealing with destructors. This leads to more than a few problem because of the way python's reference counting works.
Consider this snippet:
Which yields the following output when executed:
From this we learn that calling "del" on a reference won't do anything unless it's the last reference to that object. This is as it should be in a reference counted GC environment. In C++ however the first del would have cleaned up the object and subsequent accesses would have produced a crash.
This produces some unwanted results when a class tries to get rid of member objects (e.g. the SimpleVehicle's tires) while still holding a reference to them (in this case, in the self.tires list). The tires are not actually cleaned up and the application crashes on exit.
The python way of getting rid of objects is just getting rid of the reference, e.g. by setting it to None and letting the GC take care of the rest.
In the case of the simplevehicle the fix is easy: before doing "del self.Car" when escape is pressed, you have to eliminate the reference loop. "self.Car.tires=[]" will do nicely.
Consider this snippet:
class A(object):
def __del__(self):
print "Destructor called"
a = A()
b = a
print id(a)
print id(b)
del a
print id(b)
del b
Which yields the following output when executed:
12123856
12123856
12123856
Destructor called
From this we learn that calling "del" on a reference won't do anything unless it's the last reference to that object. This is as it should be in a reference counted GC environment. In C++ however the first del would have cleaned up the object and subsequent accesses would have produced a crash.
This produces some unwanted results when a class tries to get rid of member objects (e.g. the SimpleVehicle's tires) while still holding a reference to them (in this case, in the self.tires list). The tires are not actually cleaned up and the application crashes on exit.
The python way of getting rid of objects is just getting rid of the reference, e.g. by setting it to None and letting the GC take care of the rest.
In the case of the simplevehicle the fix is easy: before doing "del self.Car" when escape is pressed, you have to eliminate the reference loop. "self.Car.tires=[]" will do nicely.