浅谈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中的列表知识点汇总
Apr 14 Python
编写Python脚本来实现最简单的FTP下载的教程
May 04 Python
python3实现全角和半角字符转换的方法示例
Sep 21 Python
解决Scrapy安装错误:Microsoft Visual C++ 14.0 is required...
Oct 01 Python
python双端队列原理、实现与使用方法分析
Nov 27 Python
浅析Python数字类型和字符串类型的内置方法
Dec 22 Python
Python 字符串处理特殊空格\xc2\xa0\t\n Non-breaking space
Feb 23 Python
python读取多层嵌套文件夹中的文件实例
Feb 27 Python
Python基于gevent实现文件字符串查找器
Aug 11 Python
Python使用urlretrieve实现直接远程下载图片的示例代码
Aug 17 Python
使用Pytorch搭建模型的步骤
Nov 16 Python
python将YUV420P文件转PNG图片格式的两种方法
Jan 22 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
自己做矿石收音机
2021/03/02 无线电
基于qmail的完整WEBMAIL解决方案安装详解
2006/10/09 PHP
用mysql内存表来代替php session的类
2009/02/01 PHP
XHProf报告字段含义的解析
2016/05/17 PHP
php实现断点续传大文件示例代码
2020/06/19 PHP
js操作textarea 常用方法总结
2012/12/03 Javascript
纯JS实现五子棋游戏兼容各浏览器(附源码)
2013/04/24 Javascript
js兼容的placeholder属性详解
2013/08/18 Javascript
js创建一个input数组并绑定click事件的方法
2014/06/12 Javascript
js实现鼠标点击左上角滑动菜单效果代码
2015/09/06 Javascript
javascript实现网页端解压并查看zip文件
2015/12/15 Javascript
JavaScript数组去重的几种方法效率测试
2016/10/23 Javascript
JavaScript Ajax实现异步通信
2016/12/14 Javascript
javascript基础知识讲解
2017/01/11 Javascript
详解webpack + vue + node 打造单页面(入门篇)
2017/09/23 Javascript
微信web端后退强制刷新功能的实现代码
2018/03/04 Javascript
Vue组件中prop属性使用说明实例代码详解
2018/05/31 Javascript
Vue 实现从文件中获取文本信息的方法详解
2019/10/16 Javascript
vuex存储复杂参数(如对象数组等)刷新数据丢失的解决方法
2019/11/05 Javascript
javascript利用canvas实现鼠标拖拽功能
2020/07/23 Javascript
vue 中的动态传参和query传参操作
2020/11/09 Javascript
django 在原有表格添加或删除字段的实例
2018/05/27 Python
pytorch中tensor张量数据类型的转化方式
2019/12/31 Python
Python 实现平台类游戏添加跳跃功能
2020/03/27 Python
使用Django实现把两个模型类的数据聚合在一起
2020/03/28 Python
python批量修改文件名的示例
2020/09/27 Python
Html5监听手机摇一摇事件的实现
2019/11/07 HTML / CSS
Magee 1866官网:Donegal粗花呢外套和大衣专家
2019/11/01 全球购物
高级Java程序员面试题
2016/06/23 面试题
英语翻译系毕业生求职信
2013/09/29 职场文书
招聘单位介绍信
2014/01/14 职场文书
人事文员岗位职责
2014/02/16 职场文书
2014县委书记党的群众路线教育实践活动对照检查材料思想汇报
2014/09/22 职场文书
2015年推普周活动总结
2015/03/27 职场文书
2016年教师党员创先争优承诺书
2016/03/24 职场文书