[Tutor] More Doubt with classes

Terry Carroll carroll at tjc.com
Wed Jan 25 03:01:16 CET 2006


On Tue, 24 Jan 2006, my long-lost cousin Barry wrote:

> class Person:
   ...
>     def __del__(self):
>         '''I am dying.'''
>         print '%s says bye.' % self.name
>         Person.population -= 1
> 
>         if Person.population == 0:
>             print 'I am the last one.'
>         else:
>             print 'There are still %d people left.' % Person.population

> ========================================
> 
> When I ran it on my system (Windows XP Professional), I got an error as
> the script was cleaning up.  Here is the output.  
  . . . 
> Tony Danza says bye.
> Exception exceptions.AttributeError: "'NoneType' object has no attribute
> 'population'" in <bound method Person.__del__ of <__main__.Person
> instance at 0x00909BC0>> ignored
> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

I'm thinking that what's going on here is that the instances are being 
deleted as your program ends, which results in the __del__ method being 
invoked for each instance.

But as the last instance (Danza) is deleted, there are no references left
to the Person class any longer, either; and so the class itself is
deleted, and that's happening before the deletion of Danza has completed.  
Once the Person class is deleted, there is no longer any Person.population
variable.  You therefore get an AttributeError, because the attribute
"population" no longer exists; and since the person class is gone, there
isn't even the Person class to reference any longer, hence the NoneType.

I think this is what's meant in the docs on __del__:

     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.

    http://www.python.org/doc/2.4.2/ref/customization.html

In your case, Person.population is one such "other global."

If you really wanted to count on that code being executed in a timely way, 
the best way to do it is with an explicit call to a method to clean up the 
object. 

On the other hand, I'm talking just a little bit over my own head here, so 
I might be completely wrong.  But I figure it's as good a way as any to 
get a conversation started where I might learn something.




More information about the Tutor mailing list