Yield inside try...finally

Alan Kennedy alanmk at hotmail.com
Wed Jun 4 05:47:49 EDT 2003


Michael Sparks wrote:

> So the general form would be:
> 
> class Finality(Exception): pass
> 
> try:
>     thing = getThing()
>         try: # .. try, again
>             while thing.doMoreThingsThatMightBreak():
>                 yield thing
>             raise Finality
>         except Exception, x: # Where you want nested "finally"s
>             thing.necessaryShutdownFollowingFirstBreakable()
>             raise x
> except Finality: # Where you would want the last "finally"
>    pass
> except NastyExceptionThrowableByAllThoseMethods, e:
>    print "Whinge, Moan, Complain", e
> 
> I'm not convinced that I _like_ this version, but it's definitely an
> interesting alternative. (The thing I don't like is the "raise" in this
> casestrikes me as an abuse of what raise is for. I'll have a think.

Yes, it could be considered abuse, I suppose. It's just that I have a
tendency to use exceptions extensively in all my programs, because they're
such a clean way of categorising errors and problems, and raising them 
back up to the appropriate level. Since any program/system I write usually
includes a couple of dozen user defined exceptions, it seemed no harm to me
to create a new one to signify a particular event, and to use "raise" to
create it......

The real problem here is the fact that try..finally has been actively
disabled inside generators, because Guido's language designers intuition
tells him that the "contract" of finally clauses might be broken by their
use inside a generator which might never resume. 

But in your situation, where you pretty much guarantee that the generator
*will* be resumed, by your coroutine scheduler, this concern does not
apply.

Another way to look at it is this: If try..finally didn't exist in python,
then how would you achieve the same effect using try..except? That's
effectively the position that we are put in by Guido's design choice.

I think the only way is by raising your own finality exception, and sending
it through a catch-all exception handler. I genuinely cannot think of a
cleaner way to do it.

If only I had the self.confidence to raise it with Guido :-)

I looked through the other versions of your functions, and they weren't
nearly as clear as the first, desired, structure.

I'd be interested in reading about the results of your experiments with
coroutines, if you get a chance. Best of luck with it.

regards,

-- 
alan kennedy
-----------------------------------------------------
check http headers here: http://xhaus.com/headers
email alan:              http://xhaus.com/mailto/alan




More information about the Python-list mailing list