yield 的 StopIteration 请帮我解释一下

发布于 2022-09-05 19:27:22 字数 313 浏览 18 评论 0

def tt():
    x = yield
    print('x=', x)
    pass

gen = tt()
gen.send(None)            
gen.send(11)     
print('--------')
gen.close()

我的理解是,send给生成器发送数据11--->函数tt()里面执行完毕--->又回到send那里,这时候不是应该继续正常执行send后面的代码吗,send后面又没有再次调用生成器,为什么这个时候会抛出StopIteration这个异常呢? 难道send方法调用两次??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

抱猫软卧 2022-09-12 19:27:22
def tt():
    x = yield
    print('x=', x)
    return 'EXPECTED ERROR'


gen = tt()  # 获取生成器对象
print(gen)  # <generator object tt at 0x00000235C79EDF10>
gen.send(None)  # 等价于next(gen), 启动语句找到第一个yield
recv = gen.send(11)  # yield 返回None,并继续运行到下一个yield
print(recv)
#当生成器内部执行到return语句时(或者隐式的 return None),自动抛出StopIteration异常,return的值将作为异常的解释
print('--------')
gen.close()  
浅沫记忆 2022-09-12 19:27:22

过程少了一步:send给生成器发送数据11--->函数tt()里面执行完毕--->找下一个yield语句--->又回到send那里,因为这里它找下一个yield语句找不到,所以就会报StopIteration异常。

第一个send(None)走到第一个yield这里,因为生成器刚启动的第一次是不执行的,而只是悬空等待。第二次send(11),才开始执行赋值语句x = yield,但执行完之后,它又会寻觅下一个yield进行等待,因为找不到,所以就报错。

只需要把pass改成yield就可以了:

def tt():
    x = yield
    print('x=', x)
    yield

gen = tt()
gen.send(None)            
gen.send(11)     
print('--------')
gen.close()

实际上yield这个词有阻止和等待的意思,你看一看美国的路牌就知道了:

clipboard.png

在几乎所有小路上大路的地方,都立有这样的标志,类似于中国的缓行避让的意思。所以在这里,一看见yield,马上就停止,大概就是这个意思。

江湖彼岸 2022-09-12 19:27:22

很简单,函数执行完 当然抛出 异常

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文