On Sun, Feb 1, 2009 at 11:52 PM, <jwal...@vsnl.net> wrote: > Hi All, > > Here is a sample piece of code with which I am having a problem, with > Python version 2.4.4 > > class Person: > Count = 0 # This represents the count of objects of this class > > def __init__(self, name): > self.name = name > print name, ' is now created' > Person.Count += 1 > > def __del__(self): > print self.name, ' is now deleted' > Person.Count -= 1 > if Person.Count == 0: > print 'The last object of Person class is now deleted' > else: > print 'There are still', Person.Count, ' objects of class Person' > > x2 = Person("Krishna") > del x2 > > When the above code is executed, it works properly. > > If the last statement del x2, is removed, then when the program terminates, > this throws up an exception as shown below > > Krishna is now created > Krishna is now deleted > Exception exceptions.AttributeError: "'NoneType' object has no attribute > 'Count' > " in <bound method Person.__del__ of <__main__.Person instance at > 0xf6532f6c>> ignored > > Can someone please explain why the exception happens in the case where there > is no explicit del statement?
Without the `del`, the reference count of x2 remains >0 and so is not deleted until the program ends. This affects when __del__ is executed, which matters greatly. >From the section on __del__ on http://www.python.org/doc/2.3.5/ref/customization.html : Warning: Due to the precarious circumstances under which __del__() methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed to sys.stderr instead. Also, when __del__() is invoked in response to a module being deleted (e.g., when execution of the program is done), ***other globals referenced by the __del__() method may already have been deleted***. For this reason, __del__() methods should do the absolute minimum needed to maintain external invariants. [etc., emphasis mine] Since without the `del`, __del__ is only called at the end of the program, Person and/or Count may have already been GC-ed by the time __del__ is called (the order objects are GC-ed in is a bit unpredictable), hence the error you get which is saying, in a slightly obtuse way, that Person has been GC-ed already. As the Warning states, __del__ shouldn't be relied upon to do fancy stuff like you're having it do. You would be better off using an explicit finalizer method in this case, like .close() for file objects. For example: try: x2 = Person("Krishna") #do stuff with x2 finally: x2.delete() #causes count to be decremented Cheers, Chris -- Follow the path of the Iguana... http://rebertia.com -- http://mail.python.org/mailman/listinfo/python-list