浅谈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 相关文章推荐
Centos5.x下升级python到python2.7版本教程
Feb 14 Python
探究Python中isalnum()方法的使用
May 18 Python
python executemany的使用及注意事项
Mar 13 Python
python django 增删改查操作 数据库Mysql
Jul 27 Python
机器学习python实战之决策树
Nov 01 Python
用python处理图片实现图像中的像素访问
May 04 Python
用Python和WordCloud绘制词云的实现方法(内附让字体清晰的秘笈)
Jan 08 Python
Django 使用easy_thumbnails压缩上传的图片方法
Jul 26 Python
Python中 CSV格式清洗与转换的实例代码
Aug 29 Python
python在不同条件下的输入与输出
Feb 13 Python
Python sorted排序方法如何实现
Mar 31 Python
如何在scrapy中集成selenium爬取网页的方法
Nov 18 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
真正面向对象编程:PHP5.01发布
2006/10/09 PHP
PHP将回调函数作用到给定数组单元的方法
2014/08/19 PHP
PHP DB 数据库连接类定义与用法示例
2019/03/11 PHP
破解Session cookie的方法
2006/07/28 Javascript
Js之软键盘实现(js源码)
2007/01/30 Javascript
对google个性主页的拖拽效果的js的完整注释[转]
2007/04/10 Javascript
js中继承的几种用法总结(apply,call,prototype)
2013/12/26 Javascript
iframe窗口高度自适应的实现方法
2014/01/08 Javascript
解决html按钮切换绑定不同函数后点击时执行多次函数问题
2014/05/14 Javascript
jQuery多媒体插件jQuery Media Plugin使用详解
2014/12/19 Javascript
jQuery焦点图插件SaySlide
2015/12/21 Javascript
Angular实现form自动布局
2016/01/28 Javascript
全面解析Bootstrap中scrollspy(滚动监听)的使用方法
2016/06/06 Javascript
jquery制做精致的倒计时特效
2016/06/13 Javascript
vue slot 在子组件中显示父组件传递的模板
2018/03/02 Javascript
JavaScript ES6中的简写语法总结与使用技巧
2018/12/30 Javascript
vue中进行微博分享的实例讲解
2019/10/14 Javascript
vue实现计步器功能
2019/11/01 Javascript
[52:31]VP vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
tornado捕获和处理404错误的方法
2014/02/26 Python
Python中定时任务框架APScheduler的快速入门指南
2017/07/06 Python
Python常见内置高效率函数用法示例
2018/07/31 Python
对Python中list的倒序索引和切片实例讲解
2018/11/15 Python
Python 添加文件注释和函数注释操作
2020/08/09 Python
行政主管岗位职责
2013/11/18 职场文书
高二地理教学反思
2014/01/24 职场文书
《大作家的小老师》教学反思
2014/04/16 职场文书
高中语文课后反思
2014/04/27 职场文书
教师职位说明书
2014/07/29 职场文书
研究生导师评语
2014/12/31 职场文书
自荐信怎么写
2015/03/04 职场文书
人事任命通知
2015/04/20 职场文书
公司借款担保书
2015/09/22 职场文书
JavaScript canvas实现流星特效
2021/05/20 Javascript
Spring Boot 实现敏感词及特殊字符过滤处理
2021/06/29 Java/Android
微信小程序中使用vant框架的具体步骤
2022/02/18 Javascript