[Python-ideas] Propagating StopIteration value
Jan Kaliszewski
zuo at chopin.edu.pl
Thu Oct 11 01:29:32 CEST 2012
> The goal described by the OP could be reached with a wrapper
> generator -- something like this:
[snip]
PS. A more convenient version (you don't need to repeat yourself):
import collections
def genfrom(iter_factory, *args):
final_value = None
def catching(iterable):
subiter = iter(iterable)
nonlocal final_value
try:
while True:
yield next(subiter)
except StopIteration as exc:
if exc.args:
final_value = exc.args[0]
raise
args = [catching(arg.iterable) if isinstance(arg, genfrom.this)
else arg
for arg in args]
yield from iter_factory(*args)
return final_value
genfrom.this = collections.namedtuple('propagate_from_this',
'iterable')
Some examples:
>>> import itertools
>>> def f():
... yield 'g'
... return 10000000
...
>>> my_chain = genfrom(itertools.chain, 'abc', 'def',
genfrom.this(f()))
>>> while True:
... print(next(my_chain))
...
a
b
c
d
e
f
g
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
StopIteration: 10000000
>>> my_filter = genfrom(filter, lambda x: True, genfrom.this(f()))
>>> next(my_filter)
'g'
>>> next(my_filter)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration: 10000000
More information about the Python-ideas
mailing list