如何在异常之后继续迭代?

2024-10-01 04:55:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我对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打印top下的所有int?

显然,gen_odd中的异常与return一样工作—它将迭代器标记为耗尽。真的是这样吗?有解决办法吗?你知道吗


Tags: intesttrueforiftopdefall
1条回答
网友
1楼 · 发布于 2024-10-01 04:55:27

except块中重新分配gen_odd()

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

一旦引发ValueError异常,生成器函数gen_odd就会停止。在前一个函数停止后,必须调用该函数才能创建另一个gen function对象。gen_odd从它停止的地方开始拾取,因为从gen_int生成的值被绑定到函数对象;状态被保存,否则这将不起作用。他说


>>> gen_test(5)
1
('gen_odd', 2)
2
3
('gen_odd', 4)
4
5
('gen_odd', 6)
6

相关问题 更多 >