Python生成器yield层级中send调用为何直达底层而非返回至top?
def bottom(): value = yield 42 print("yield expression in bottom is ", value) return value def middle(): value = yield from bottom() print("yield expression in middle is ", value) return value def top(): value = yield from middle() print("yield expression in top is ", value) return value gen = top() value = next(gen) print(value) try: gen.send(value * 2) except StopIteration as exc: value = exc.value print(value) # outputs: # 42 # yield expression in bottom is 84 # yield expression in middle is 84 # yield expression in top is 84 # 84
问题
为何send调用从top一路传递至bottom,而非返回给top生成器?我原本预期send调用传递的值会返回给top生成器。
解答
这是Python中yield from的核心委托机制决定的:
- 当使用
yield from将生成器控制权委托给子生成器时,外部的send值、next调用、异常都会直接透传到当前暂停的最内层子生成器,直到该子生成器运行结束。 - 执行
next(gen)时,生成器链会一路走到bottom()里的yield 42,此时整个生成器链的暂停点就停在bottom的这个yield表达式上,而非top或middle的yield from语句处。 - 所以调用
gen.send(84)时,这个值会沿着top→middle→bottom的委托链直接传递到bottom里的value = yield 42,让yield表达式接收84并赋值给value。 - 只有当
bottom执行完return value触发StopIteration后,它的返回值才会被middle的yield from接收,赋值给middle的value;同理middle返回后,值再传给top的yield from,最后top返回的值触发顶层的StopIteration被捕获。
简单来说:yield from是“透传”控制权的,外部send的值会直接给到当前暂停的最内层生成器,不会停在顶层的委托处。
内容的提问来源于stack exchange,提问作者nitesh yadav
相关产品推荐
相关产品推荐

