浅谈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服务器端收发请求的实现代码
Sep 29 Python
python访问系统环境变量的方法
Apr 29 Python
Python简单实现enum功能的方法
Apr 25 Python
详解Python实现多进程异步事件驱动引擎
Aug 25 Python
python钉钉机器人运维脚本监控实例
Feb 20 Python
Python单元和文档测试实例详解
Apr 11 Python
Python调用百度根据经纬度查询地址的示例代码
Jul 07 Python
Python实现栈和队列的简单操作方法示例
Nov 29 Python
基于tensorflow指定GPU运行及GPU资源分配的几种方式小结
Feb 03 Python
关于python中的xpath解析定位
Mar 06 Python
python switch 实现多分支选择功能
Dec 21 Python
python某漫画app逆向
Mar 31 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
批量修改RAR文件注释的php代码
2010/11/20 PHP
关于session在PHP5的配置文件中的详细设置参数说明
2011/04/20 PHP
php 删除一个数组中的某个值.兼容多维数组!
2012/02/18 PHP
PHP连接操作access数据库实例
2015/03/30 PHP
jQuery学习笔记之jQuery的DOM操作
2010/12/22 Javascript
另一个javascript小测验(代码集合)
2011/07/27 Javascript
js获取当前页面路径示例讲解
2014/01/08 Javascript
不使用ajax实现无刷新提交表单
2014/12/21 Javascript
JavaScript实现找质数代码分享
2015/03/24 Javascript
AngularJS中的过滤器使用详解
2015/06/16 Javascript
jQuery数据类型小结(14个)
2016/01/08 Javascript
Javascript仿京东放大镜的效果
2017/03/01 Javascript
JS实现验证码倒计时的注册页面
2018/01/02 Javascript
微信小程序实现文字跑马灯效果
2020/05/26 Javascript
vue 全选与反选的实现方法(无Bug 新手看过来)
2018/02/09 Javascript
jQuery实现鼠标移入移出事件切换功能示例
2018/09/06 jQuery
浅谈vue中使用编辑器vue-quill-editor踩过的坑
2020/08/03 Javascript
vue3.0 项目搭建和使用流程
2021/03/04 Vue.js
打开电脑上的QQ的python代码
2013/02/10 Python
Python中的__SLOTS__属性使用示例
2015/02/18 Python
从源码解析Python的Flask框架中request对象的用法
2016/06/02 Python
Python获取暗黑破坏神3战网前1000命位玩家的英雄技能统计
2016/07/04 Python
python利用urllib和urllib2访问http的GET/POST详解
2017/09/27 Python
python实现人脸识别代码
2017/11/08 Python
JS设计模式之责任链模式实例详解
2018/02/03 Python
Opencv-Python图像透视变换cv2.warpPerspective的示例
2019/04/11 Python
Python判断对象是否为文件对象(file object)的三种方法示例
2019/04/26 Python
pycharm设置python文件模板信息过程图解
2020/03/10 Python
解决使用Pandas 读取超过65536行的Excel文件问题
2020/11/10 Python
《尊严》教学反思
2014/02/11 职场文书
工作建议书范文
2014/05/13 职场文书
我的中国梦演讲稿小学篇
2014/08/19 职场文书
纪委书记群众路线整改措施思想汇报
2014/10/09 职场文书
个人公司授权委托书范本
2014/10/12 职场文书
优秀班主任事迹材料
2014/12/16 职场文书
档案管理员岗位职责
2015/02/12 职场文书