[Python-Dev] Re: anonymous blocks
Neil Schemenauer
nas at arctrix.com
Thu Apr 28 02:48:52 CEST 2005
On Wed, Apr 27, 2005 at 03:58:14PM -0700, Guido van Rossum wrote:
> Time to update the PEP; I'm pretty much settled on these semantics
> now...
[I'm trying to do a bit of Guido channeling here. I fear I may not
be entirely successful.]
The the __error__ method seems to simplify things a lot. The
purpose of the __error__ method is to notify the iterator that the
loop has been exited in some unusual way (i.e. not via a
StopIteration raised by the iterator itself).
The translation of a block-statement could become:
itr = EXPR1
arg = None
while True:
try:
VAR1 = next(itr, arg)
except StopIteration:
break
try:
arg = None
BLOCK1
except Exception, exc:
err = getattr(itr, '__error__', None)
if err is None:
raise exc
err(exc)
The translation of "continue EXPR2" would become:
arg = EXPR2
continue
The translation of "break" inside a block-statement would
become:
err = getattr(itr, '__error__', None)
if err is not None:
err(StopIteration())
break
The translation of "return EXPR3" inside a block-statement would
become:
err = getattr(itr, '__error__', None)
if err is not None:
err(StopIteration())
return EXPR3
For generators, calling __error__ with a StopIteration instance
would execute any 'finally' block. Any other argument to __error__
would get re-raised by the generator instance.
You could then write:
def opened(filename):
fp = open(filename)
try:
yield fp
finally:
fp.close()
and use it like this:
block opened(filename) as fp:
....
The main difference between 'for' and 'block' is that more iteration
may happen after breaking or returning out of a 'for' loop. An
iterator used in a block statement is always used up before the
block is exited.
Maybe __error__ should be called __break__ instead. StopIteration
is not really an error. If it is called something like __break__,
does it really need to accept an argument? Of hand I can't think of
what an iterator might do with an exception.
Neil
More information about the Python-Dev
mailing list