使用for循环与next()耗尽生成器为何返回值不同?
问题原因分析
你的问题核心在于:生成器的return值只会在第一次触发StopIteration时被携带,生成器耗尽后再次调用next()抛出的StopIteration没有value值。
我们逐行分析两个函数的执行过程:
1. exhaust_generator 函数的执行逻辑
这个函数通过while True循环不断调用next(_gen):
- 前三次调用
next(),生成器依次返回1、2、3。 - 第四次调用
next()时,生成器执行到return "done"语句,此时会抛出携带return值的StopIteration异常,异常的value属性就是"done",所以你捕获到的返回值是正确的。
2. exhaust_generator_iter 函数的执行逻辑
这个函数的问题出在for循环之后的next(_gen)调用:
for i in _gen本质是自动迭代生成器,每次调用__next__(),直到生成器抛出StopIteration。当生成器执行到return "done"时,确实会抛出携带"done"的StopIteration,但for循环会自动捕获这个异常并终止循环,不会把这个异常暴露出来。- 循环结束后,生成器已经处于耗尽状态,你再次调用
next(_gen)时,生成器会抛出一个全新的、没有携带value的StopIteration异常,所以此时e.value是None。
验证修改
如果想在exhaust_generator_iter里拿到生成器的return值,应该把迭代逻辑改成手动调用next(),比如:
def exhaust_generator_iter_fixed(_gen): print("===============================================") print("exhaust_generator_iter_fixed") try: while True: print(next(_gen)) except StopIteration as e: print(f"Return value: '{e.value}'")
这样执行就会和第一个函数得到一样的结果。
内容的提问来源于stack exchange,提问作者Chicky
相关产品推荐
相关产品推荐

