对于普通的生成器,第一个next调用,相当于启动生成器,会从生成器函数的第一行代码开始执行,直到第一次执行完yield语句(第4行)后,跳出生成器函数。
然后第二个next调用,进入生成器函数后,从yield语句的下一句语句(第5行)开始执行,然后重新运行到yield语句,执行后,跳出生成器函数,后面再次调用next,依次类推。
下面是一个列子:
1
2
3
4
5
6
7
8
9
10
|
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相比,只是开始多了一次赋值的动作,其他运行流程是相同的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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) |
运行结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[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的运行流程(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。