Re: Exception error when accessing the class variable at the termination of the program
jwal...@vsnl.net wrote: > Can someone please explain why the exception happens in the case > where there is no explicit del statement? When Python is ecleaning up as it exits, it clears all the global variables in each module by setting them to None. This happens in an arbitrary and unpredictable order: in this particular case it set Person to None before setting x2 to None. If you must have a __del__ method on a class then you should take care not to access any globals from inside the __del__ method (or any function it calls). Alternatively you could just catch and ignore any exceptions thrown from your __del__ method. In the example you gave, provided you never subclass Person you could use self.__class__.Count to access your class variable. However in many cases you'll probably find that a much better solution is to use weak references. e.g. a WeakValueDictionary mapping id(self) to self: from weakref import WeakValueDictionary class Person: _instances = WeakValueDictionary() def __init__(self, name): self.name = name self._instances[id(self)] = self print name, 'is now created' @property def Count(self): return len(self._instances) def __del__(self): print self.name, 'is now deleted' if self.Count==0: print 'The last object of Person class is now deleted' else: print 'There are still', self.Count, 'objects of class Person' x2 = Person('Krishna') # del x2 -- Duncan Booth http://kupuguy.blogspot.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Exception error when accessing the class variable at the termination of the program
On Sun, Feb 1, 2009 at 11:52 PM, 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 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
Exception error when accessing the class variable at the termination of the program
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 > ignored Can someone please explain why the exception happens in the case where there is no explicit del statement? Thanks Jana -- http://mail.python.org/mailman/listinfo/python-list