深入认识yield

    在generator中,我们不但可以通过for循环来迭代(用法一),还可以不断调用next()函数获取由yield语句返回的下一个值(用法一)

    但是Pythonyield不但可以返回一个值yield语句右边),它还可以接收调用者发出的参数(yield语句左边)

def h():
    print('To be brave')
    m=yield 5
    print(m)
    print('To be brave2')
    n=yield 6
    print(n)

c=h()
s=next(c) #第一次调用,发送空值,s接受5
k=c.send('g') #第二次调用,发送g给m,k接受下一个yield语句返回6
print(s,k)

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

         yield语句从上一个yield左边参数接受参数开始,从下一个yield右边返回参数结束。


利用yield语句实现协程生产者与消费者问题:

def consumer():
    r = ''
    while True:
        n = yield r       
        if not n:            
            return
        print('[CONSUMER] Consuming %s...' % n)
        r = '200 OK'
def produce(c):
    c.send(None)
    n = 0
    while n < 5:
        n = n + 1
        print('[PRODUCER] Producing %s...' % n)
        r = c.send(n)
        print('[PRODUCER] Consumer return: %s' % r)
    c.close()

c = consumer()
produce(c)

执行结果:

[PRODUCER] Producing 1...
[CONSUMER] Consuming 1...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 2...
[CONSUMER] Consuming 2...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 3...
[CONSUMER] Consuming 3...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 4...
[CONSUMER] Consuming 4...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 5...
[CONSUMER] Consuming 5...
[PRODUCER] Consumer return: 200 OK

注意到consumer函数是一个generator,把一个consumer传入produce后:

  1. 首先调用c.send(None)启动生成器;

  2. 然后,一旦生产了东西,通过c.send(n)切换到consumer执行;

  3. consumer通过yield拿到消息,处理,又通过yield把结果传回;

  4. produce拿到consumer处理的结果,继续生产下一条消息;

  5. produce决定不生产了,通过c.close()关闭consumer,整个过程结束。


你可能感兴趣的:(深入认识yield)