Python嵌套生成器模拟无限数据流时输出不符合预期问题排查
问题根因
- 子生成器未被完整迭代:你在
_get_data的循环逻辑中,每次都会创建新的_data_yielder实例,仅调用next()获取它第一次yield的返回值后就直接丢弃了该实例,没有继续迭代子生成器的后续内容,所以每个字母只会输出索引为0的结果。 - send值未向下传递:你对外层
_get_data生成器调用send()方法时,传入的值是发送给外层生成器的,而原代码中_get_data没有任何接收send值并传递给子生成器的逻辑,所以_data_yielder里的bla变量永远拿不到你传入的值,自然不会有对应的打印输出。
修复方案
使用Python的yield from语法处理子生成器即可,yield from会自动完成两层生成器的透传逻辑:一方面把子生成器yield的所有值直接返回给最外层的调用方,另一方面也会把外层调用方的send、throw等操作自动转发给子生成器,完全匹配你的使用需求。
仅需要修改_get_data函数的最后一行即可,修改后的完整代码如下:
def _data_yielder(v, iter_to): for i in range(iter_to): bla = yield (v, i) print(f"Result received from send: {bla}") def _get_data(): """ generator that iterates some expensive-to-open files """ for i, v in enumerate(["A", "B", "C"]): offset = i + 2 print(f"{v} should go up to {(v, offset-1)}") # 替换原有的yield next逻辑为yield from yield from _data_yielder(v, offset) def _reset(): resetted_generator = _get_data() initial_value = next(resetted_generator) return initial_value, resetted_generator count = 0 iter_data, data_generator_process = _reset() print(f"\toutput value: {iter_data}") while True: try: iter_data = data_generator_process.send(f"test_{count}") count += 1 print(f"\toutput value: {iter_data}") except StopIteration as e: print(e) break except Exception as e: print(e)
运行效果
修改后运行即可得到你预期的输出,同时你send的test_{count}值也会被_data_yielder正确接收并打印,输出内容如下:
A should go up to ('A', 1) output value: ('A', 0) Result received from send: test_0 output value: ('A', 1) B should go up to ('B', 2) Result received from send: test_1 output value: ('B', 0) Result received from send: test_2 output value: ('B', 1) C should go up to ('C', 3) Result received from send: test_3 output value: ('C', 0) Result received from send: test_4 output value: ('C', 1) Result received from send: test_5
内容的提问来源于stack exchange,提问作者IanQ
相关产品推荐
相关产品推荐

