为什么耗尽的发电机不止一次提高StopIteration?

max*_*max 5 python generator python-3.x

为什么当一个耗尽的发电机被多次调用StopIteration时,每次都会被调用,而不是仅仅是第一次尝试?后续调用是否毫无意义,并指出调用者代码中可能存在错误?

def gen_func():
    yield 1
    yield 2
gen = gen_func()
next(gen)
next(gen)
next(gen) # StopIteration as expected
next(gen) # why StopIteration and not something to warn me that I'm doing something wrong
Run Code Online (Sandbox Code Playgroud)

当有人意外使用过期的生成器时,这也会导致此行为:

def do_work(gen):
    for x in gen:
        # do stuff with x
        pass

    # here I forgot that I already used up gen
    # so the loop does nothing without raising any exception or warning
    for x in gen:
        # do stuff with x
        pass

def gen_func():
    yield 1
    yield 2

gen = gen_func()
do_work(gen)
Run Code Online (Sandbox Code Playgroud)

如果第二次和以后尝试调用耗尽的生成器引发了一个不同的异常,那么捕获这种类型的错误会更容易.

也许有一个重要的用例,用于多次调用耗尽的生成器并获得StopIteration

use*_*ica 4

也许有一个重要的用例,可以多次调用耗尽的生成器并获取StopIteration

具体来说,当您想要在同一个迭代器上执行多个循环时。itertools以下是依赖此行为的文档示例:

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)
Run Code Online (Sandbox Code Playgroud)