RE: does python have useless destructors?

Discussion in 'Python' started by Robert Brewer, Jun 10, 2004.

  1. 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
    Robert Brewer, Jun 10, 2004
    #1
    1. Advertising

  2. Robert Brewer

    Duncan Booth Guest

    "Robert Brewer" <> wrote in
    news::

    > 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.


    I'll try to explain my intention a bit more clearly. As you note, if the
    try block throws then you don't need to re-raise the exception. What I was
    trying to do was to handle the case where the dispose code throws an
    exception. If that happens when we already have an exception, then I want
    to mask the second exception and continue with the first, but if it happens
    when there is no exception I want the exception to be thrown.

    I am quite willing to be persuaded though that the correct action would be
    that an exception thrown in the dispose be allowed to mask the inner
    exception.



    >
    > def dispose(localdict, argnames):

    you meant *argnames

    > for name in argnames:
    > obj = localdict.get(name)
    > if obj:
    > try:
    > dispfunc = obj.__dispose__
    > except AttributeError:
    > pass
    > else:
    > dispfunc()
    >


    Close, but not quite there. I think you need to ensure that all of the
    __dispose__ methods *must* be called, even if an earlier one fails.
    Duncan Booth, Jun 10, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael P. Soulier

    does python have useless destructors?

    Michael P. Soulier, Jun 9, 2004, in forum: Python
    Replies:
    138
    Views:
    2,156
    Christos TZOTZIOY Georgiou
    Jun 22, 2004
  2. Delaney, Timothy C (Timothy)

    RE: does python have useless destructors?

    Delaney, Timothy C (Timothy), Jun 10, 2004, in forum: Python
    Replies:
    4
    Views:
    246
    Tim Bradshaw
    Jun 14, 2004
  3. Tim Peters
    Replies:
    2
    Views:
    297
    Paul Rubin
    Jun 12, 2004
  4. Tim Peters
    Replies:
    7
    Views:
    3,580
    David Turner
    Jun 18, 2004
  5. Delaney, Timothy C (Timothy)

    RE: does python have useless destructors?

    Delaney, Timothy C (Timothy), Jun 15, 2004, in forum: Python
    Replies:
    2
    Views:
    399
    Ype Kingma
    Jun 15, 2004
Loading...

Share This Page