Mailing List Archive

__del__ and AttributeError problem
I have 3 files:

$ cat foo.py
import bar

class foo:

def __init__(self):
self.i = 0
self.j = bar.bar()
bar.something()

def __del__(self):
print "foo dies\n"
bar.something()

x = foo()

$ cat bar.py
def something():
print "bar something\n"

class bar:

def __init__(self):
self.i = 0

def __del__(self):
print "bar dies\n"

$ cat m.py
import bar
from foo import *

$ python m.py
bar something

foo dies

Exception exceptions.AttributeError: "'None' object has no attribute 'something'" in <method foo.__del__ of foo instance at 80ad0c0> ignored
bar dies


Now for the question: why do I get the attribute error ? And what is
the right way to handle the situation ? I'm using python 1.5.1.

-Arun
__del__ and AttributeError problem [ In reply to ]
Arun Sharma writes:

> class foo:
/snip snip/

> def __del__(self):
> print "foo dies\n"
> bar.something()
/snip snip/
> Exception exceptions.AttributeError: "'None' object has no attribute
> 'something'" in <method foo.__del__ of foo instance at 80ad0c0>
> ignored bar dies
>
>
> Now for the question: why do I get the attribute error ? And what is
> the right way to handle the situation ? I'm using python 1.5.1.

Because of the order in which things happen when Python cleans up. If
you really have to do something in a __del__ method which might get
invoked by Python's cleanup, you need to do:

def __del__(self, something=bar.something):
print "foo dies\n"
something()

Now bar.something is bound to a default argument which is held deep
in the bowels of the __del__ method, so it won't go away until the
containing class gets cleaned out.

Note: this is also a valuable optimization trick. It's significantly
faster to get the default arg than it is to look up "bar.something".

- Gordon