2021-06-11

python的send方法原理

生成器的 send方法是如何运作的?为什么当生成器被挂起时用它才有意义?

第一个疑问

看一段代码:

>>> def test(val=0):
    while True:
        y = yield val
        print(y)
 
>>> t = test() # 启用生成器
>>> next(t) 
0
>>> next(t)
None
0
这段代码是Next的使用,但唯独有一个疑问:

为什么第二次Next调用后,print(y)输出了None,而不是 0 ? 

因为赋值语句从等号右边开始

第一次Next调用后,执行等号右边的表达式 yield val,执行完后函数暂停运行,赋值操作根本没有被执行。

当第二次再运行时才执行赋值(等号左半部分),而生成器恢复运行时,yield初始值为None,所以 y = None

这段代码中Next返回的始终是 0 ,如何在外部与生成器沟通,让她返回不一样的值? 于是用到了send方法

为什么可以不同

再来看send方法:

>>> def test(val=0):
    while True:
        y = yield val
        val = y 
 
>>> t = test()
>>> next(t)
0
>>> t.send('Hello,world')
'Hello,world'
send方法包含与next同样的效果,但还能为生成器传值。

在第一个例子中,第二次运行Next时yield初始值为None,导致将None赋给了y,而不是0。

在本例中使用send恢复生成器,yield初始值不是None,而是send的参数'Hello,world'

所以,send方法与next的不同在于: send首先给生成器传值,再执行和Next相同的操作( 从上次暂停的地方开始,执行到下一个yield )  send(None) 等价于 Next

所以为什么第一次运行生成器send参数只能为None? 因为send首先执行赋值操作,而生成器第一次启动,要赋值给谁?

Because generator-iterators begin execution at the top of the generator's function body, there is no yield expression to receive a value when the generator has just been created. Therefore, calling send() with a non-None argument is prohibited when the generator iterator has just started, and a TypeError is raised if this occurs (presumably due to a logic error of some kind). Thus, before you can communicate with a coroutine you must first call next() or send(None) to advance its execution to the first yield expression.

总结

当有如 y = yield x 这样的句子时,首先执行等号右半部分,再将结果赋给 y,但显然执行完yield就被冻结了,赋值只能在下一次运行生成器时执行,而下一次初始值为None。
send方法可以为生成器传值,send(None) 等价于 Next()
第一次运行生成器时如果用send方法,参数只能为None
————————————————
版权声明:本文为CSDN博主「Sheng_1225」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_28915777/article/details/108186963

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值