博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
9、【转载】Python生成器generator之next和send运行流程
阅读量:6071 次
发布时间:2019-06-20

本文共 2356 字,大约阅读时间需要 7 分钟。

def consumer():    r = 'here'    for i in range(3):        yield r        r = '200 OK' + str(i)c = consumer()n1 = next(c)n2 = next(c)n3 = next(c)

对于普通的生成器,第一个next调用,相当于启动生成器,会从生成器的第一行代码开始执行,直到第一次执行完yield语句后,中断,将r值返回并暂时跳出生成器函数。

然后第二个next调用,进入生成器函数后,从yield语句的下一句语句开始执行,然后重新运行到yield语句,执行后,跳出生成器函数,

后面再次调用next,依次类推。

 

了解了next()如何让包含yield的函数执行后,我们再来看另外一个非常重要的函数send(msg)。

其实next()和send()在一定意义上作用是相似的,区别是send()可以传递yield表达式的值进去,而next()不能传递特定的值,只能传递None进去。因此,我们可以看做c.next() 和 c.send(None) 作用是一样的

需要提醒的是,第一次调用时,请使用next()语句或是send(None),不能使用send发送一个非None的值,否则会出错的,因为没有Python yield语句来接收这个值。

如果在编辑器中将send(None)注释掉,直接发送一个非None的值,则回报错:

Traceback (most recent call last):  File "D:/PycharmProjects/hello/test.py", line 23, in 
produce(c) File "D:/PycharmProjects/hello/test.py", line 18, in produce r1 = c.send(n)TypeError: can't send non-None value to a just-started generator

个人理解:调用send(非None值)传入参数,就要有相对应的yield语句接受参数!第一次调用先调用send(None),与next()作用一样,均是在generator中将程序执行定位到yield语句,为了下次传入非None值时接收。这可能时python的一种机制吧。

 

下面来着重说明下send执行的顺序:

# -*- coding: utf-8 -*-def consumer():    r = ''    while True:        n1 = yield r        if not n1:            return        print('[CONSUMER] Consuming %s...' % n1)        r = '200 OK'def produce(c):    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)

当第一次执行c.send(None)时,启动生成器,从生成器函数的第一行代码开始执行,直到第一次执行到 n1 = yield r 后,跳出生成器函数。这个过程中,n1一直没有定义,如图所示:

 

下面运行到 r1 = c.send(1) 时,进入生成器函数,注意这里与调用next的不同。

 这里是从 n1 = yield r 开始执行,把1赋值给n1,但是并不执行yield部分

下面继续从yield的下一语句继续执行,然后重新运行到yield语句,执行 yield r 后,跳出生成器函数!

即send和next相比,只是开始多了一次赋值的动作,其他运行流程是相同的。

 

运行结果:

[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

 

备注:转载自http://blog.csdn.net/pfm685757/article/details/49924099,并添加个人的见解

posted on
2018-03-15 20:53 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/zwb8848happy/p/8576214.html

你可能感兴趣的文章
kafka的分区分配策略
查看>>
react-keeper
查看>>
react 项目实战(十)引入AntDesign组件库
查看>>
flexible.js + makegrid.js 自适应布局
查看>>
js 判断对象中所有属性是否为空
查看>>
Scrapy基础(六)————Scrapy爬取伯乐在线一通过css和xpath解析文章字段
查看>>
spring MVC 运行过程
查看>>
19、其他文件编程函数(目录文件、链接文件、临时文件)
查看>>
Java LinkList遍历方式
查看>>
little w and Segment Coverage
查看>>
nginx-rtmp加入权限验证的简单方法
查看>>
《javascript高级程序设计》第一版笔记
查看>>
我的 FPGA 学习历程(09)—— 时序逻辑入门
查看>>
开发中遇到的抗
查看>>
Struts2输入校验2(框架效验)———struts2第四讲
查看>>
Eclipse安装propertie预览插件
查看>>
两个二极管反向并联一般起什么作用
查看>>
防错笔记
查看>>
Mybatis中sql语句中的in查询,一定要判断null的情况
查看>>
Ping命令简单报错介绍
查看>>