关于python中yield和协程的一点理解

yield一般应用于生成循环中的那个变量,一般这个变量是在代码编写时候就固定的或者是在生成器建立时候就传入的值

例如:

def a():
    i = 0
    while True:
        yield i
        i += 2

def b(j):
    i = 0
    while True:
        yield i
        i += j

但是

Python的yield不但可以返回一个值,它还可以接收调用者发出的参数

def consumer():
    # 4.第一次send的None不赋值给任何变量
    r = None
    while True:
        n = yield r # 5.yield返回r,此时并没有赋值给n
        # 8.将第二次send的1赋值给n,并继续执行直到下一次碰到yield的时候
        if not n:
            return
        print('[CONSUMER] Consuming %s ...' % n )
        r = '200 OK'

def produce(c):
    # 2.先执行produce函数
    r = c.send(None) # 3.这句话等价于c.next() 此时开始执行consumer()
    # 6.将生成器yield返回的None赋值给r,继续往下执行
    n = 0
    while n < 5:
        n = n + 1
        print('[PRODUCER] Producing %s ...' % n )
        r = c.send(n) # 7. 发送n给consumer()
        # 9.将第二次yield的200 OK赋值给r,继续执行直到下一次send()或者next()
        print('[PRODUCER Consumer return: %s' % r)
    c.close()

c = consumer() # 1.这句话的时候consumer没有被执行
produce(c)

在生成器的协程模型中,调用者不执行到next()或者send()是不会执行任何生成器的代码,而一旦执行到了这两个方法就会进入生成器执行,在生成器执行的时候只有碰见yield才会跳出去执行调用者的代码。

yield在执行的时候,先把后面的值返回就去执行调用者的代码,直到碰见send()的时候才会把传进来的值赋值给其前面的变量(这个时候next()等价于send(None)

相关日志

  1. 2018.08.08

    [微信公众号文章抓取.一]探索各种办法的可行性

    最近在公司做了一个这方面的项目,总结一下。顺…

  2. 2018.09.14

    再用dict.keys()就是狗

    最近刷题用python比较多,毕竟list比…

  3. 2018.08.21

    [微信公众号文章抓取.二]构建Anyproxy来获取数据

    上回书说到,啊啊呸。上一篇文章已经确定了抓取…

  4. 2018.06.07

    python爬虫:提取页面时间

    def date_check(date_st…

  5. 2018.03.20

    使用正则表达式解析url

    #!/usr/bin/env python …

  6. 2018.03.20

    python-单向链表

    一个简单的单向链表类 (更多……

评论

还没有评论。

在此评论中不能使用 HTML 标签。