calling destructor in python multiply-inherited class
Duncan Booth
me at privacy.net
Thu May 20 07:45:12 EDT 2004
rajorshi at fastmail.fm (Rajorshi) wrote in
news:85b5e3f8.0405200259.468161f3 at posting.google.com:
> In the destructor of the derived class, if I write something like this
>
> def __del__(self):
> for b in self.__class__.__bases__:
> b.__del__(self)
>
> then its working fine, but if I am doing something straightforward
> like
>
> def __del__(self):
> Base1.__del__(self)
> Base2.__del__(self)
>
> Its giving an error like :
> Exception exceptions.AttributeError: "'NoneType' object has no
> attribute '__del__'" in <bound method Derv.__del__ of <__main__.Derv
> instance at 0x8187484>> ignored
>
> Obviously I'm doing something wrong ! Any pointers ??
>
I guess this error occurs when your program is exiting. When a Python
program terminates the global variables in each module are set to None. The
order in which this happens it undefined, so when your __del__ method gets
called the global Base1, or maybe Base2, has already been cleared. The base
classes still exist, so you can access them through your class, but the
names they used will have been rebound.
A reasonable conclusion from this is:
A __del__ method must never access *any* global variables unless it is
prepared to handle the consequences of the global not existing.
Next question, do you really need to use __del__? Remember that Python will
not always call the __del__ method at the time you expect, and that the
behaviour will vary on different Python implementations. Also the existence
of a __del__ method is sufficient to prevent your object ever being
released from a cycle by the garbage collector. If you need explicit tidy
up, use a dispose pattern instead of depending on __del__.
There is very little that you can usefully do inside a __del__ method.
Deleting contained objects is pointless (it happens automatically without
you doing it in __del__). Closing a file should be done explicitly when you
are finished with it because if you try to do it in __del__ and the call to
__del__ is delayed you will get unexpected problems.
If you really need to call __del__ on more than one base class, use the
super() builtin to do it.
More information about the Python-list
mailing list