浅谈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实现partial改变方法默认参数
Aug 18 Python
Python类属性的延迟计算
Oct 22 Python
python 字符串转列表 list 出现\ufeff的解决方法
Jun 22 Python
Python实现的knn算法示例
Jun 14 Python
在PyCharm中三步完成PyPy解释器的配置的方法
Oct 29 Python
python 获得任意路径下的文件及其根目录的方法
Feb 16 Python
Python多线程threading模块用法实例分析
May 22 Python
Python实现直方图均衡基本原理解析
Aug 08 Python
浅谈keras使用预训练模型vgg16分类,损失和准确度不变
Jul 02 Python
详解基于Scrapy的IP代理池搭建
Sep 29 Python
Python实现我的世界小游戏源代码
Mar 02 Python
使用Python开发贪吃蛇游戏 SnakeGame
Apr 30 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
php去掉URL网址中带有PHPSESSID的配置方法
2014/07/08 PHP
PHP基于接口技术实现简单的多态应用完整实例
2017/04/26 PHP
js局部刷新页面时间具体实现
2013/07/04 Javascript
对 jQuery 中 data 方法的误解分析
2014/06/18 Javascript
node.js中实现同步操作的3种实现方法
2014/12/05 Javascript
解析javascript中鼠标滚轮事件
2015/05/26 Javascript
谷歌Chrome浏览器扩展程序开发小记
2016/01/06 Javascript
jQuery常用的一些技巧汇总
2016/03/26 Javascript
BootStrap智能表单实战系列(十一)级联下拉的支持
2016/06/13 Javascript
JavaScript动态添加css样式和script标签
2016/07/19 Javascript
轻松掌握JavaScript享元模式
2016/08/27 Javascript
JS实现判断图片是否加载完成的方法分析
2018/07/31 Javascript
vue element中axios下载文件(后端Python)
2019/05/10 Javascript
Vue.js 中制作自定义选择组件的代码附演示demo
2020/02/28 Javascript
vuecli3.x中轻松4步带你使用tinymce的步骤
2020/06/25 Javascript
[01:00:13]完美世界DOTA2联赛 LBZS vs Forest 第一场 11.07
2020/11/09 DOTA
[59:00]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD BO3 第一场 3月7日
2021/03/11 DOTA
Python实现在Linux系统下更改当前进程运行用户
2015/02/04 Python
python fabric使用笔记
2015/05/09 Python
Python标准库sched模块使用指南
2017/07/06 Python
Python反射的用法实例分析
2018/02/11 Python
pip install urllib2不能安装的解决方法
2018/06/12 Python
Python之列表的插入&amp;替换修改方法
2018/06/28 Python
django获取from表单multiple-select的value和id的方法
2019/07/19 Python
Python中如何将一个类方法变为多个方法
2019/12/30 Python
Python日志打印里logging.getLogger源码分析详解
2021/01/17 Python
会计实习期自我鉴定
2013/10/06 职场文书
运动会表扬稿大全
2014/01/16 职场文书
工厂门卫岗位职责范本
2014/04/04 职场文书
幼儿园保育员岗位职责
2014/04/13 职场文书
学生安全责任书范本
2014/07/24 职场文书
教师师德师风个人整改方案
2014/09/18 职场文书
学生会主席任命书
2015/09/21 职场文书
公司周年庆寄语
2019/06/21 职场文书
史上最全书信经典范文大全(建议收藏)
2019/07/10 职场文书
浅谈resultMap的用法及关联结果集映射
2021/06/30 Java/Android