浅谈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 django集成cas验证系统
Jul 14 Python
python复制文件的方法实例详解
May 22 Python
python实现按行切分文本文件的方法
Apr 18 Python
基于Python socket的端口扫描程序实例代码
Feb 09 Python
Python实现删除时保留特定文件夹和文件的示例
Apr 27 Python
浅谈解除装饰器作用(python3新增)
Oct 15 Python
使用urllib库的urlretrieve()方法下载网络文件到本地的方法
Dec 19 Python
python 遍历列表提取下标和值的实例
Dec 25 Python
Python3.7+tkinter实现查询界面功能
Dec 24 Python
python中判断文件结束符的具体方法
Aug 04 Python
10个python爬虫入门实例(小结)
Nov 01 Python
python爬虫用request库处理cookie的实例讲解
Feb 20 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
example1.php
2006/10/09 PHP
用PHP伪造referer突破网盘禁止外连的代码
2008/06/15 PHP
PHP实现多条件查询实例代码
2010/07/17 PHP
网页上facebook分享功能具体实现
2014/01/26 PHP
php高清晰度无损图片压缩功能的实现代码
2018/12/09 PHP
laravel框架使用极光推送消息操作示例
2020/02/15 PHP
元素的内联事件处理函数的特殊作用域在各浏览器中存在差异
2011/01/12 Javascript
解析JavaScript中instanceof对于不同的构造器或许都返回true
2013/12/03 Javascript
自己使用jquery写的一个无缝滚动的插件
2014/04/30 Javascript
JavaScript实现找出数组中最长的连续数字序列
2014/09/03 Javascript
jQuery插件ajaxFileUpload异步上传文件
2016/10/19 Javascript
微信小程序蓝牙连接小票打印机实例代码详解
2019/06/03 Javascript
js实现文字头像的生成代码
2020/03/07 Javascript
[02:17]DOTA2亚洲邀请赛 RAVE战队出场宣传片
2015/02/07 DOTA
python将xml xsl文件生成html文件存储示例讲解
2013/12/03 Python
python实现斐波那契递归函数的方法
2014/09/08 Python
Python实现mysql数据库更新表数据接口的功能
2017/11/19 Python
pandas string转dataframe的方法
2018/04/11 Python
使用Python实现一个栈判断括号是否平衡
2018/08/23 Python
Python 判断图像是否读取成功的方法
2019/01/26 Python
如何使用Python自动控制windows桌面
2019/07/11 Python
python操作gitlab API过程解析
2019/12/27 Python
Pytorch 实现权重初始化
2019/12/31 Python
python利用datetime模块计算程序运行时间问题
2020/02/20 Python
关于Python turtle库使用时坐标的确定方法
2020/03/19 Python
快速解决jupyter notebook启动需要密码的问题
2020/04/21 Python
python实现自动打卡的示例代码
2020/10/10 Python
CSS3 画基本图形,圆形、椭圆形、三角形等
2016/09/20 HTML / CSS
皮姆斯勒语言学习:Pimsleur Language Programs
2018/06/30 全球购物
安踏官方商城:anta.cn
2019/12/16 全球购物
Parfumdreams芬兰:购买香水和化妆品
2021/02/13 全球购物
普通话宣传标语
2014/06/26 职场文书
化学专业大学生职业生涯规划范文
2014/09/13 职场文书
人大代表选举标语
2014/10/07 职场文书
祝福语集锦:送给毕业同学祝福语
2019/11/21 职场文书
如何用Laravel包含你自己的帮助函数
2021/05/27 PHP