如何在异常后继续迭代?

时间:2016-10-26 16:09:28

标签: python python-2.7 iterator

我对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起作用 - 它将迭代器标记为耗尽。这是真的吗?有解决方法吗?

1 个答案:

答案 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