浅谈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回溯法实现数组全排列输出实例分析
Mar 17 Python
详解Python中 __get__和__getattr__和__getattribute__的区别
Jun 16 Python
Python 3.x 连接数据库示例(pymysql 方式)
Jan 19 Python
Django实现快速分页的方法实例
Oct 22 Python
python Crypto模块的安装与使用方法
Dec 21 Python
python sys,os,time模块的使用(包括时间格式的各种转换)
Apr 27 Python
浅谈Pycharm调用同级目录下的py脚本bug
Dec 03 Python
详解pandas数据合并与重塑(pd.concat篇)
Jul 09 Python
python如何求数组连续最大和的示例代码
Feb 04 Python
django项目中新增app的2种实现方法
Apr 01 Python
通过代码简单了解django model序列化作用
Nov 12 Python
Python函数中的不定长参数相关知识总结
Jun 24 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 执行系统外部命令 system() exec() passthru()
2009/08/11 PHP
php文件打包 下载之使用PHP自带的ZipArchive压缩文件并下载打包好的文件
2012/06/13 PHP
php_screw 1.5:php加密: 安装与使用详解
2013/06/20 PHP
ThinkPHP 3.2 数据分页代码分享
2014/10/14 PHP
CL vs ForZe BO5 第五场 2.13
2021/03/10 DOTA
脚本安需导入(装载)的三种模式的对比
2007/06/24 Javascript
JQuery为textarea添加maxlength属性的代码
2010/04/07 Javascript
js判断某个方法是否存在实例代码
2015/01/10 Javascript
js检测用户输入密码强度
2015/10/22 Javascript
给easyui的datebox控件添加清空按钮的实现方法
2016/11/09 Javascript
清除js缓存的多种方法总结
2016/12/09 Javascript
原生js实现简单的焦点图效果实例
2017/12/14 Javascript
JS使用H5实现图片预览功能
2019/09/30 Javascript
vue-router 2.0 跳转之router.push()用法说明
2020/08/12 Javascript
[41:54]2018DOTA2亚洲邀请赛 4.1 小组赛A组加赛 TNC vs Liquid
2018/04/03 DOTA
Python urlopen 使用小示例
2008/09/06 Python
在Python中实现贪婪排名算法的教程
2015/04/17 Python
Python 爬虫学习笔记之正则表达式
2016/09/21 Python
python itchat实现微信自动回复的示例代码
2017/08/14 Python
itchat和matplotlib的结合使用爬取微信信息的实例
2017/08/25 Python
浅谈numpy库的常用基本操作方法
2018/01/09 Python
pycharm设置注释颜色的方法
2018/05/23 Python
Python爬虫文件下载图文教程
2018/12/23 Python
python GUI库图形界面开发之PyQt5窗口背景与不规则窗口实例
2020/02/25 Python
Python猴子补丁Monkey Patch用法实例解析
2020/03/23 Python
css3实现超炫风车特效
2014/11/12 HTML / CSS
加拿大便宜的隐形眼镜商店:Clearly
2016/09/15 全球购物
俄罗斯购买剧院和演唱会门票网站:Parter.ru
2019/11/09 全球购物
工程类专业自荐信范文
2014/03/09 职场文书
《特殊的葬礼》教学反思
2014/04/27 职场文书
党员教师批评与自我批评发言稿
2014/10/15 职场文书
单位介绍信格式范文
2015/05/04 职场文书
初三毕业感言
2015/07/31 职场文书
2016高考感言
2015/08/01 职场文书
Java Spring 控制反转(IOC)容器详解
2021/10/05 Java/Android
Linux中sftp常用命令整理
2022/06/28 Servers