try: finally: question

Donn Cave donn at u.washington.edu
Wed Jul 7 14:11:15 EDT 2004


In article <40ec2dbc at usenet01.boi.hp.com>, djw <donald.welch at hp.com> 
wrote:

> Peter Hansen wrote:
> 
> [snip]
> > 
> > Hmm... Also, I think it really *is* unusual (as in, "not usual"
> > meaning not really common) to nest try blocks.  At least, I
> > recall lone try/finally or try/except blocks being much much
> > more common in most code than a mix.  Perhaps my memory is
> > poor on this.  Perhaps someone will actually go and research
> > it and prove it one way or the other.  If it really is
> > very common, it might be worth revisiting the subject...
> > If it's not very common, then this is once again just another
> > discussion about syntactic sugar for an uncommon use case,
> > and that kind of thing is so last year.  And the year before.
> > And....
> > 
> > -Peter
> 
> I am suprised that what I am trying to accomplish is unusual. Basically, I
> want to acquire some resource/object (that requires cleanup). Then make
> some calls against that object/resource, catching any excpetions along the
> way (assuming that try/except is the right way to do this). If anything bad
> happens, I want stop opererating on the object and insure that the object
> is cleaned up (presumably a finally is the best way to do this). 
> 
> This seems like a really normal bit of code to me. I am suprised there isn't
> a more elegant way to handle this (I thought that try/except/finally would
> come to the rescue, but...) Is there a better way to handle this situation?

Not per se.  My reflex would be to suggest more functions,
like

   def f(p0, p1):
       t = acquire_resource(p0)
       try:
           v = ft(p1)
       finally:
           release_resource(t)
       return v

   def ft(p1):
       try:
           x = g(p1)
       except Eg, ev:
           print >> sys.stderr, ev
           return None
       try:
           return fx(x)
       except:
           gu(x)
           raise

   def fx(x):
       try:
           return fy(h(x))
       except Eh, ev:
           print >> sys.stderr, ev
           raise

etc.  Note that the exception handling will be more or
less elaborate depending on how much you can take for
granted about what exceptions may be raised, what state
you need to recover from them, etc.'

Conceptually, what you're after is a nested try: block,
like

   try:
       x = g(p1)
       try:
           y = h(x)
           try:
               ...
           except:
               ...
       except:
           handle h error
   except:
        handle g error

That's how you handle an exception from g without
proceeding to h, with try/except alone.  I don't find
that grossly wrong, it's just more palatable with a
few functions when it gets very deep.

   Donn Cave, donn at u.washington.edu



More information about the Python-list mailing list