[Python-Dev] Re: anonymous blocks
Phillip J. Eby
pje at telecommunity.com
Wed Apr 27 22:59:46 CEST 2005
At 01:27 PM 4/27/05 -0700, Guido van Rossum wrote:
>[Phillip Eby]
> > Very nice. It's not clear from the text, btw, if normal exceptions can be
> > passed into __next__, and if so, whether they can include a traceback. If
> > they *can*, then generators can also be considered co-routines now, in
> > which case it might make sense to call blocks "coroutine blocks", because
> > they're basically a way to interleave a block of code with the execution of
> > a specified coroutine.
>
>The PEP is clear on this: __next__() only takes Iteration instances,
>i.e., StopIteration and ContinueIteration. (But see below.)
>
>I'm not sure what the relevance of including a stack trace would be,
>and why that feature would be necessary to call them coroutines.
Well, you need that feature in order to retain traceback information when
you're simulating threads with a stack of generators. Although you can't
return from a generator inside a nested generator, you can simulate this by
keeping a stack of generators and having a wrapper that passes control
between generators, such that:
def somegen():
result = yield othergen()
causes the wrapper to push othergen() on the generator stack and execute
it. If othergen() raises an error, the wrapper resumes somegen() and
passes in the error. If you can only specify the value but not the
traceback, you lose the information about where the error occurred in
othergen().
So, the feature is necessary for anything other than "simple" (i.e.
single-frame) coroutines, at least if you want to retain any possibility of
debugging. :)
>But... Maybe it would be nice if generators could also be used to
>implement exception handling patterns, rather than just resource
>release patterns. IOW, maybe this should work:
>
> def safeLoop(seq):
> for var in seq:
> try:
> yield var
> except Exception, err:
> print "ignored", var, ":", err.__class__.__name__
>
> block safeLoop([10, 5, 0, 20]) as x:
> print 1.0/x
Yes, it would be nice. Also, you may have just come up with an even better
word for what these things should be called... patterns. Perhaps they
could be called "pattern blocks" or "patterned blocks". Pattern sounds so
much more hip and politically correct than "macro" or even "code block". :)
>An alternative that solves this would be to give __next__() a second
>argument, which is a bool that should be true when the first argument
>is an exception that should be raised. What do people think?
I think it'd be simpler just to have two methods, conceptually
"resume(value=None)" and "error(value,tb=None)", whatever the actual method
names are.
More information about the Python-Dev
mailing list