<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=us-ascii" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Yup, I think Carsten got it.  Mystery solved!<br>
<br>
You could replace Person with self.__class__ instead of type(self) if
Person is an old-style class (since the class won't be collected until
after all the instances are collected (because each instance references
it's class)).  Note that when the name "Person" is set to None, the
Person class has it's reference count reduced by one but it is not yet
collected.<br>
<br>
Alternatively, if you name your locals to start with "_" (e.g. _cathy)
you avoid this problem<br>
<i>"Starting with version 1.5, Python guarantees that globals whose
name begins with a single underscore are deleted from their module
before other globals are deleted; if no other references to such
globals exist, this may help in assuring that imported modules are
still available at the time when the <tt class="method">__del__()</tt>
method is called."</i><br>
<br>
But in general, I have this to say:  IMO __del__ should not be taught
to beginners (other than to say "don't use __del__ yet; you have much
to learn first young jedi").  It should always be put in the "advanced
topics" section when included in beginning python books along with
threads, process control, and extending/embedding.  If you think you
need it, you probably don't.<br>
<br>
It is an advanced concept that requires a basic understanding of
garbage collection.  Beginners shouldn't really have to know much about
garbage collection.  The whole point is that it is automatic.<br>
<br>
__del__ is particularly dangerous for experienced C++ programmers
starting to learn Python.  People look for analogies and when they see
__del__ they think "destructor" which is sort of vaguely right, but
completely wrong in practice.  The practical difference is that in C++
you actually have to deal with implementing destructors all of the
time, and you can't get very far as a C++ programmer without using
them, whereas in python you almost never have to deal with
destructors.  In C++, destructors are usually predictable (in correct
code), but in python code they are somewhat harder to predict because
they are invoked implicitly at the whim of the python implementation.<br>
<br>
In practice you don't need to use __del__ unless you are doing
something exotic like explicitly implementing your own memory model, or
tuning resource allocation in a large system.  If you are doing
ordinary day-to-day programming don't even think about __del__.<br>
<br>
Ken Seehart<br>
<br>
<br>
Carsten Haese wrote:
<blockquote cite="mid1206320551.3365.20.camel@localhost.localdomain"
 type="cite">
  <pre wrap="">On Sun, 2008-03-23 at 17:42 -0700, George Sakkis wrote:
  </pre>
  <blockquote type="cite">
    <pre wrap="">That's really weird... it's reproducible on Windows too. It doesn't
make any sense why the name of the variable would make a difference.
My guess is you hit some kind of obscure bug.
    </pre>
  </blockquote>
  <pre wrap=""><!---->
This is not a bug, just an unexpected feature:
<a class="moz-txt-link-freetext" href="http://mail.python.org/pipermail/python-list/2005-January/304873.html">http://mail.python.org/pipermail/python-list/2005-January/304873.html</a>

What's happening is that at the end of the script, all objects in the
global namespace are set to None (in order to decrease their reference
count and trigger garbage collection). This happens in the order in
which the names appear as keys in the globals dictionary. It randomly
happens that "swaroop", "kalam", and "cath" all are hashed in front of
"Person", but "cathy" is hashed after "Person".

Hence, if Catherine is named cath, Python "None's" all the instances
first and then the type last, and all is well. However, if Catherine is
called cathy, Person is set to None before cathy. Then, in the lookup of
the global name "Person" during cathy.__del__, Person is None, which
doesn't have a "population" attribute, causing the AttributeError.

Possible workarounds are:
1) Explicitly delete the global names for the instances before the
script runs out.
2) Don't refer to the "Person" type by its global name in __del__, but
indirectly as type(self). (This requires Person to be a new-style class,
though.)

  </pre>
</blockquote>
<br>
</body>
</html>