Python生成器generator之next和send运行流程

原创 2015年11月19日 10:59:38


对于普通的生成器,第一个next调用,相当于启动生成器,会从生成器函数的第一行代码开始执行,直到第一次执行完yield语句(第4行)后,跳出生成器函数。

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

后面再次调用next,依次类推。下面是一个列子:

1 def consumer():
2     r = 'here'
3     for i in xrange(3):
4         yield r
5         r = '200 OK'+ str(i)
6
7 c = consumer()
8 n1 = c.next()
9 n2 = c.next()
10 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相比,只是开始多了一次赋值的动作,其他运行流程是相同的。

1 def consumer():
2     r = 'here'
3     while True:
4         n1 = yield r
5         if not n1:
6             return
7         print('[CONSUMER] Consuming %s...' % n1)
8         r = '200 OK'+str(n1)
9
10 def produce(c):
11     aa = c.send(None)
12     n = 0
13     while n < 5:
14         n = n + 1
15         print('[PRODUCER] Producing %s...' % n)
16         r1 = c.send(n)
17         print('[PRODUCER] Consumer return: %s' % r1)
18     c.close()
19
20 c = consumer()
21 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初探(二)

前言 生成器 概念 实例用法 生成器推导式 与生成器交互 生成器高级用法 使用建议 总结 前言前一段时间项目上线,太忙了。今天趁着周六,继续Generator的探索之旅。上一篇,我们介绍过了迭代器的...
  • lidajunguyu
  • lidajunguyu
  • 2015年06月06日 08:56
  • 842

python中的generator高级用法 -- send

def yield_tester(self):         value = yield         if value:             yield value         ...
  • qugang1982
  • qugang1982
  • 2014年01月19日 21:07
  • 772

python特性(八):生成器对象的send方法

生成器对象是一个迭代器。但是它比迭代器对象多了一些方法,它们包括send方法,throw方法和close方法。这些方法,主要是用于外部与生成器对象的交互。本文先介绍send方法。 send方法有一...
  • hedan2013
  • hedan2013
  • 2017年02月21日 19:57
  • 3369

Python:yield关键字以及next、send函数的作用

yield与生成器 def func(n): for i in range(0, n): print('func: ', i) # yield i f = f...
  • mingC0758
  • mingC0758
  • 2016年12月21日 12:21
  • 3558

生成器对象的send方法

转载
  • baidu_38127162
  • baidu_38127162
  • 2017年05月01日 22:36
  • 339

Python之美[从菜鸟到高手]--生成器之全景分析

yield指令,可以暂停一个函数并返回中间结果。使用该指令的函数将保存执行环境,并且在必要时恢复。 生成器比迭代器更加强大也更加复杂,需要花点功夫好好理解贯彻。 看下面一段代码: def gen():...
  • yueguanghaidao
  • yueguanghaidao
  • 2013年08月23日 01:13
  • 15901

理解python的generator

对python generator自认为比较容易理解的讲解
  • Leonard_wang
  • Leonard_wang
  • 2017年02月27日 17:36
  • 991

python socket函数中,send 与sendall的区别与使用方法

在python socket编程中,有两个发送TCP的函数,send()与sendall()
  • pdmwg
  • pdmwg
  • 2014年09月12日 10:31
  • 15511

python socket编程详细介绍

Python 提供了两个基本的 socket 模块。    第一个是 Socket,它提供了标准的 BSD Sockets API。    第二个是 SocketServer, 它提供了服...
  • rebelqsp
  • rebelqsp
  • 2014年03月25日 23:21
  • 129782

关于python中send发送十六进制的方法

由于经常从wireshark中抓数据包,需放在python进行发送,但socket中的send发送与c不同,终于找到一种可以将c数组转换为python socket send数据的方法,特此记录! ...
  • aphero
  • aphero
  • 2016年02月27日 14:49
  • 2736
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Python生成器generator之next和send运行流程
举报原因:
原因补充:

(最多只允许输入30个字)