does python have useless destructors?
Robert Brewer
fumanchu at amor.org
Thu Jun 10 11:27:17 EDT 2004
Duncan Booth wrote:
> 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.
AFAICT, you don't need to reraise the exception. Example:
>>> try:
... f
... finally:
... print 'finally'
...
finally
Traceback (most recent call last):
File "<interactive input>", line 2, in ?
NameError: name 'f' is not defined
But I could be wrong--perhaps you've got a requirement I can't see on
first glance. Given that, perhaps we can simplify your example to:
def f(filename):
try:
infile = file(filename, "r")
outfile = file(filename+".out", "w")
outfile.write(infile.read())
finally:
for _temp in ['outfile', 'infile']:
if _temp in locals():
try:
locals()[_temp].__dispose__()
except:
pass
...which could be rewritten as (totally untested)...
def dispose(localdict, argnames):
for name in argnames:
obj = localdict.get(name)
if obj:
try:
dispfunc = obj.__dispose__
except AttributeError:
pass
else:
dispfunc()
def f(filename):
try:
infile = file(filename, "r")
outfile = file(filename+".out", "w")
outfile.write(infile.read())
finally:
dispose(locals(), 'infile', 'outfile')
Write dispose once and drop it somewhere accessible in my site...a
rather convenient idiom. Thanks! I think I'll pursue it.
Robert Brewer
MIS
Amor Ministries
fumanchu at amor.org
More information about the Python-list
mailing list