[Numpy-discussion] usage of __del__ in python classes

David Cournapeau david at ar.media.kyoto-u.ac.jp
Wed Jan 31 23:04:03 EST 2007


Sebastian Haase wrote:
> Hi,
> Before I start I want to admit that I don't understand much about
> this. I just saw that the memmap class defines __del__ and that I had
> problems in the past when I added a 'def __del__' to a class of mine.
> So here is a quote, I would like to know if this is "standard
> knowledge" on this list or not.
>
>     # I found the info originally here: http://arctrix.com/nas/python/gc/
>     # Circular references which are garbage are detected when the
> optional cycle detector is enabled (it's on by default), but can only
> be cleaned up if there are no Python-level __del__() methods involved.
> Refer to the documentation for the 'gc' module for more information
> about how __del__() methods are handled by the cycle detector,
> particularly the description of the garbage value. Notice: [warning]
> Due to the precarious circumstances under which __del__() methods are
> invoked, exceptions that occur during their execution are ignored, and
> a warning is printed to sys.stderr instead. 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. For this reason, __del__() methods
> should do the absolute minimum needed to maintain external invariants.
>
>
This is particularly annoying when using ctypes, and you need to clean 
some ressources. I had this problem with pyaudiolab:

Class A
def __init__(self):
# here call C library open
def close(self):
# here dispose of all handlers related to the file
def __del__(self):
# here dipose of all handlers (if not cleaned by close)

As mentionned in the above paragraph, the problem is that sometimes 
(typically, when exiting the python interpreter) the C library reference 
is "out of scope" (not sure the expressionis appropriate for python) 
before calling __del__ on an instance of A. I am using ctypes for the 
interface with C in this case, so what I do is:

def __del__(self, close_func = _snd.sf_close):
# Stupid python needs the close_func, otherwise
# it may clean ctypes before calling here
if not(self.hdl == 0):
close_func(self.hdl)
self.hdl = 0

This is not pretty, and you better not call __del__ with your own 
close_func function, but that's the only solution I can think of.

David




More information about the NumPy-Discussion mailing list