浅谈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 相关文章推荐
Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法
May 22 Python
Python中特殊函数集锦
Jul 27 Python
python类:class创建、数据方法属性及访问控制详解
Jul 25 Python
Python基础知识_浅谈用户交互
May 31 Python
Python实现决策树C4.5算法的示例
May 30 Python
Python3爬虫学习之MySQL数据库存储爬取的信息详解
Dec 12 Python
python查询文件夹下excel的sheet名代码实例
Apr 02 Python
NumPy 基本切片和索引的具体使用方法
Apr 24 Python
python中使用ctypes调用so传参设置遇到的问题及解决方法
Jun 19 Python
python3安装crypto出错及解决方法
Jul 30 Python
详解python中docx库的安装过程
Nov 08 Python
Python生成六万个随机,唯一的8位数字和数字组成的随机字符串实例
Mar 03 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的Html模板标签使用方法
2012/11/13 PHP
PHP 自定义错误处理函数的使用详解
2013/05/10 PHP
在云虚拟主机部署thinkphp5项目的步骤详解
2017/12/21 PHP
PHP设计模式之注册树模式分析
2018/01/26 PHP
PHP常量及变量区别原理详解
2020/08/14 PHP
extJs 文本框后面加上说明文字+下拉列表选中值后触发事件
2009/11/27 Javascript
JS对文本框值的判断示例
2014/03/10 Javascript
JS延时提示框实现方法详解
2015/11/26 Javascript
JS实现为排序好的字符串找出重复行的方法
2016/03/02 Javascript
js 提交form表单和设置form表单请求路径的实现方法
2016/10/25 Javascript
angular+ionic 的app上拉加载更新数据实现方法
2017/01/16 Javascript
JavaScript求一个数组中重复出现次数最多的元素及其下标位置示例
2018/07/23 Javascript
es6中Promise 对象基本功能与用法实例分析
2020/02/23 Javascript
Vue左滑组件slider使用详解
2020/08/21 Javascript
vue-cli3访问public文件夹静态资源报错的解决方式
2020/09/02 Javascript
深入理解Python中各种方法的运作原理
2015/06/15 Python
python selenium UI自动化解决验证码的4种方法
2018/01/05 Python
基于python的ini配置文件操作工具类
2019/04/24 Python
使用python分析统计自己微信朋友的信息
2019/07/19 Python
pytorch 图像中的数据预处理和批标准化实例
2020/01/15 Python
使用 tf.nn.dynamic_rnn 展开时间维度方式
2020/01/21 Python
简单了解pytest测试框架setup和tearDown
2020/04/14 Python
keras实现VGG16 CIFAR10数据集方式
2020/07/07 Python
苹果美国官方商城:Apple美国
2016/08/24 全球购物
Nanushka官网:匈牙利服装品牌
2019/08/14 全球购物
机械专业毕业生自荐信
2013/11/02 职场文书
婚礼主持词
2014/03/13 职场文书
营销部内勤岗位职责
2014/04/30 职场文书
本科生导师推荐信范文
2014/05/18 职场文书
五一活动标语
2014/06/30 职场文书
现实表现材料范文
2014/12/23 职场文书
欢迎词怎么写
2015/01/23 职场文书
毕业论文致谢范文
2015/05/14 职场文书
幼儿园毕业致辞
2015/07/29 职场文书
小学大队长竞选稿
2015/11/20 职场文书
每日六道java新手入门面试题,通往自由的道路
2021/06/30 Java/Android