Does python hate cathy?
ken at seehart.com
Mon Mar 24 02:52:12 CET 2008
Yup, I think Carsten got it. Mystery solved!
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
Alternatively, if you name your locals to start with "_" (e.g. _cathy)
you avoid this problem
/"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 __del__() method is called."/
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.
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.
__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.
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__.
Carsten Haese wrote:
> On Sun, 2008-03-23 at 17:42 -0700, George Sakkis wrote:
>> 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.
> This is not a bug, just an unexpected feature:
> 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,
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Python-list