浅谈Python生成器generator之next和send的运行流程(详解)


Posted in Python onMay 08, 2017

对于普通的生成器,第一个next调用,相当于启动生成器,会从生成器函数的第一行代码开始执行,直到第一次执行完yield语句(第4行)后,跳出生成器函数。

然后第二个next调用,进入生成器函数后,从yield语句的下一句语句(第5行)开始执行,然后重新运行到yield语句,执行后,跳出生成器函数,后面再次调用next,依次类推。

下面是一个列子:

def consumer():
   r = 'here'
   for i in xrange(3):
     yield r
     r = '200 OK'+ str(i)

 c = consumer()
 n1 = c.next()
 n2 = c.next()
 n3 = c.next()

了解了next()如何让包含yield的函数执行后,我们再来看另外一个非常重要的函数send(msg)。其实next()和send()在一定意义上作用是相似的,区别是send()可以传递yield表达式的值进去,而next()不能传递特定的值,只能传递None进去。因此,我们可以看做c.next() 和 c.send(None) 作用是一样的。

需要提醒的是,第一次调用时,请使用next()语句或是send(None),不能使用send发送一个非None的值,否则会出错的,因为没有Python yield语句来接收这个值。

下面来着重说明下send执行的顺序。当第一次send(None)(对应11行)时,启动生成器,从生成器函数的第一行代码开始执行,直到第一次执行完yield(对应第4行)后,跳出生成器函数。这个过程中,n1一直没有定义。

下面运行到send(1)时,进入生成器函数,注意这里与调用next的不同。这里是从第4行开始执行,把1赋值给n1,但是并不执行yield部分。下面继续从yield的下一语句继续执行,然后重新运行到yield语句,执行后,跳出生成器函数。

即send和next相比,只是开始多了一次赋值的动作,其他运行流程是相同的。

def consumer():
   r = 'here'
   while True:
     n1 = yield r
     if not n1:
       return
     print('[CONSUMER] Consuming %s...' % n1)
     r = '200 OK'+str(n1)

 def produce(c):
   aa = c.send(None)
   n = 0
   while n < 5:
     n = n + 1
     print('[PRODUCER] Producing %s...' % n)
     r1 = c.send(n)
     print('[PRODUCER] Consumer return: %s' % r1)
   c.close()

 c = consumer()
 produce(c)

 运行结果:

[PRODUCER] Producing 1...
[CONSUMER] Consuming 1...
[PRODUCER] Consumer return: 200 OK1
[PRODUCER] Producing 2...
[CONSUMER] Consuming 2...
[PRODUCER] Consumer return: 200 OK2
[PRODUCER] Producing 3...
[CONSUMER] Consuming 3...
[PRODUCER] Consumer return: 200 OK3
[PRODUCER] Producing 4...
[CONSUMER] Consuming 4...
[PRODUCER] Consumer return: 200 OK4
[PRODUCER] Producing 5...
[CONSUMER] Consuming 5...
[PRODUCER] Consumer return: 200 OK5

以上这篇浅谈Python生成器generator之next和send的运行流程(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现抓取网页并且解析的实例
Sep 20 Python
python错误处理详解
Sep 28 Python
python计算一个序列的平均值的方法
Jul 11 Python
PHP网页抓取之抓取百度贴吧邮箱数据代码分享
Apr 13 Python
python判断字符串是否是json格式方法分享
Nov 07 Python
TensorFlow深度学习之卷积神经网络CNN
Mar 09 Python
python批量修改文件编码格式的方法
May 31 Python
Flask模拟实现CSRF攻击的方法
Jul 24 Python
python导包的几种方法(自定义包的生成以及导入详解)
Jul 15 Python
Python3如何对urllib和urllib2进行重构
Nov 25 Python
Python读写csv文件流程及异常解决
Oct 20 Python
Python中可变和不可变对象的深入讲解
Aug 02 Python
python生成式的send()方法(详解)
May 08 #Python
python实时分析日志的一个小脚本分享
May 07 #Python
python分割列表(list)的方法示例
May 07 #Python
Python 常用的安装Module方式汇总
May 06 #Python
python中OrderedDict的使用方法详解
May 05 #Python
Python编程生成随机用户名及密码的方法示例
May 05 #Python
Python实现统计文本文件字数的方法
May 05 #Python
You might like
ThinkPHP中的关联模型注意点
2014/06/16 PHP
PHPMAILER实现PHP发邮件功能
2018/04/18 PHP
实例介绍PHP删除数组中的重复元素
2019/03/03 PHP
php 使用 __call实现重载功能示例
2019/11/18 PHP
PHP实现简易用户登录系统
2020/07/10 PHP
JavaScript 学习笔记 Black.Caffeine 09.11.28
2009/11/30 Javascript
过虑特殊字符输入的js代码
2010/08/05 Javascript
JavaScript中各种编码解码函数的区别和注意事项
2010/08/19 Javascript
jQuery渐变发光导航菜单的实例代码
2013/03/27 Javascript
IE的事件传递-event.cancelBubble示例介绍
2014/01/12 Javascript
JavaScript中合并数组的N种方法
2014/09/16 Javascript
AngularJS中的过滤器使用详解
2015/06/16 Javascript
简介AngularJS的HTML DOM支持情况
2015/06/17 Javascript
理解javascript中的MVC模式
2016/01/28 Javascript
javascript特效实现——当前时间和倒计时效果的简单实例
2016/07/20 Javascript
jQuery的图片轮播插件PgwSlideshow使用详解
2016/08/11 Javascript
JS+canvas动态绘制饼图的方法示例
2017/09/12 Javascript
如何选择适合你的JavaScript框架
2017/11/20 Javascript
基于vue-draggable 实现三级拖动排序效果
2020/01/10 Javascript
vue+vant 上传图片需要注意的地方
2021/01/03 Vue.js
在Python中使用lambda高效操作列表的教程
2015/04/24 Python
Python3爬虫使用Fidder实现APP爬取示例
2018/11/27 Python
在PyCharm下使用 ipython 交互式编程的方法
2019/01/17 Python
使用django实现一个代码发布系统
2019/07/18 Python
Pytorch在dataloader类中设置shuffle的随机数种子方式
2020/01/14 Python
在python中list作函数形参,防止被实参修改的实现方法
2020/06/05 Python
python创建文本文件的简单方法
2020/08/30 Python
美国宠物商店:Wag.com
2016/10/25 全球购物
2014公安机关纪律作风整顿思想汇报
2014/09/13 职场文书
授权委托书(公民个人适用)
2014/09/19 职场文书
教师学习党的群众路线教育实践活动心得体会
2014/10/31 职场文书
表扬稿范文
2015/01/17 职场文书
工会工作个人总结
2015/03/03 职场文书
社区服务活动感想
2015/08/11 职场文书
Python 如何安装Selenium
2021/05/06 Python
Win11 引入 Windows 365 云操作系统,适应疫情期间混合办公模式:启动时直接登录、模
2022/04/06 数码科技