我对Python-2迭代器和异常之间的交互感到困惑。
具体来说,给出以下代码:
def gen_int():
if not hasattr(gen_int,"x"):
gen_int.x = 0
while True:
gen_int.x += 1
yield gen_int.x
def gen_odd():
for x in gen_int():
if x % 2:
yield x
else:
raise ValueError("gen_odd",x)
(请假设以上是我的控制!),我写
def gen_all():
it = gen_odd()
while True:
try:
yield it.next()
except ValueError as exn:
print exn
func_name, x = exn
assert func_name == "gen_odd"
yield x
希望恢复gen_int
生成的完整流。
然而,迭代在第一个异常后停止:
def gen_test(top):
for x in gen_all():
print x
if x > top:
break
以下是3次调用:
>>> gen_test(20)
1
('gen_odd', 2)
2
>>> gen_test(20)
3
('gen_odd', 4)
4
>>> gen_test(20)
5
('gen_odd', 6)
6
问题是:
如何修改gen_all
,以便gen_test
在<{1}}下面打印所有的整数?
PS。显然,top
中的异常作为gen_odd
起作用 - 它将迭代器标记为耗尽。这是真的吗?有解决方法吗?
答案 0 :(得分:4)
在gen_odd()
区块中重新分配except
:
def gen_all():
it = gen_odd()
while True:
try:
yield it.next()
except ValueError as exn:
print exn
func_name, x = exn
assert func_name == "gen_odd"
yield x
it = gen_odd() # here
生成gen_odd
异常后,生成器函数ValueError
停止。您必须回忆起在前一个停止后创建另一个gen函数对象的函数。 gen_odd
从它停止的位置开始拾取,因为gen_int
的屈服值绑定到函数对象;状态被保存,否则这不会有效。
>>> gen_test(5)
1
('gen_odd', 2)
2
3
('gen_odd', 4)
4
5
('gen_odd', 6)
6