does python have useless destructors?

Duncan Booth me at privacy.net
Thu Jun 10 04:13:44 EDT 2004


hanzspam at yahoo.com.au (Hannu Kankaanp??) wrote in 
news:840592e1.0406092318.532f475a at posting.google.com:

> I'd very much prefer something simpler that leaves no room
> for errors, e.g.
> 
> with myfile = file("myfilepath", "w"):
>     myfile.write(reallybigbuffer)
> 
> (this, and more generic solutions with code blocks have been
> suggested here many times)
> 

One of the downsides to this form is that when you are working with several 
variables that need finalising you end up nested quite deep.

Apparently the next release of Microsoft's C++ for managed environments 
will handle the issue in quite a nice way. They will let you declare 
managed heap based objects as though they are on the stack, and if the 
object supports their dispose pattern the compiler automatically inserts 
the required try..finally block. Python might need an extra keyword, but 
perhaps it could benefit from something similar.

e.g.

def f(filename):
   dispose infile, outfile

   infile = file(filename, "r")
   outfile = file(filename+".out", "w")
   outfile.write(infile.read())

would be equivalent to something like:

def f(filename):
   try:
      infile = file(filename, "r")
      outfile = file(filename+".out", "w")
      outfile.write(infile.read())
   finally:
      _inexception = sys.exc_info()[0] is not None
      for _temp in ['outfile', 'infile']:
          if _temp in locals():
              try:
                  locals()[_temp].__dispose__()
              except:
                  pass
      if not _inexception and sys.exc_info()[0] is not None:
          raise

Obviously the keyword might be something other than dispose, and the method 
called to dispose of the object might have a different name. Plus I'm not 
sure I got the logic right on what the equivalent code should be (which I 
think is an argument *for* a scheme such as this). It should be ignoring 
variables which aren't yet set, and preserving the original exception if 
there is one, but if any __dispose__ throws an exception that should be 
propogated while not preventing all other __dispose__ methods also being 
called.



More information about the Python-list mailing list