zoukankan      html  css  js  c++  java
  • Python生成器generator之next和send运行流程

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

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

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

    #!/usr/bin/env python
    def consumer():
        r = 'here'
        for i in range(3):
            yield r
            r = '200 OK '+ str(i)
    
    c = consumer()
    n1 = next(c)
    print(n1)
    n2 = next(c)
    print(n2)
    n3 = next(c)
    print(n3)

    了解了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

  • 相关阅读:
    牛客练习赛64 C 序列卷积之和 (推式子 数学)
    HDU 汉诺塔系列
    牛客挑战赛40 A-小V和方程 (思维、数学、整数拆分、dp)
    HDU 2048 2049 (错位排列)
    组合数奇偶性判断
    bzoj 1249: SGU277 HERO
    CF70D Professor's task
    P3829 [SHOI2012]信用卡凸包
    CF316E3 Summer Homework
    P5284 [十二省联考2019]字符串问题
  • 原文地址:https://www.cnblogs.com/wenxingxu/p/9512146.html
Copyright © 2011-2022 走看看