zoukankan      html  css  js  c++  java
  • 对yield 的理解

      最近在学习Python的时候看到yield的相关语法,感觉很独特,相比其他如C/C++的语法比较有意思,于是在看完资料相关章节做一个总结。

      yield 是一个类似于 return的语法,但是对于return 而言,在其执行之后,意味着将数据返回给调用者,子程序结束,但是yield却不一样,它能够继续执行,直到下一个yield 转交执行权,之后又可以进入继续执行,周而复始,直到抛出异常。

      for in range()是一个简单有用的循环,之前的学习知道range()返回的是一个对象,有惰性求值的特点,下面是一个利用yield简单模拟range()函数的特点

    def xrange(m):
        n=m
        while(n):
            n-=1
            yield n
    for i in xrange(5):
        print(i)

    结果:

    '''
    4
    3
    2
    1
    0
    '''

    这种独特语法现象的原因,从书中摘出相关资料如下:

      当函数中使用yield产生一个值的时候,调用函数会返回一个generator对象,也就是一个生成器,此对象有__next__()方法,通常会调用next()调用该方法取出下一个产生的值,若无法产生下一个值,就会发生StopIteration这样的异常  --《Python程序设计教程》

    除了解释以上现象,反之也可推测 for in 函数的参数可以是生成器,生成器具有惰性求值特点,推测之前遇到过惰性求值的都是生成器(推测)

    yield可以通过send函数来产生值,下面用一个课本上的DEMO来熟悉其相关函数的使用,课本完成了一个生产者消费者模型:

    import random
    def producer():
        while True:
            data=random.randint(0,9)
            print('生产了:',data)
            yield data
    def consumer():
        while True:
            data=yield
            print('消费了:',data)
    def clerk(jobs,producer,consumer):
        print('执行了{}次生产与消费'.format(jobs))
        p=producer()
        c=consumer()
        next(c)           #这里容易出错
        for i in range(jobs):
            data=next(p)
            c.send(data)
    clerk(5,producer,consumer)    

    上面注释的地方比较有意思,只是执行一次yield,而没有任何输出,似乎是没用,但是删除之后程序却无法执行,我的理解是必须执行一次使值转化成生成器对象才能接受相关数据。

    为了印证我的观点,执行以下代码:

    print(type(producer))
    print(type(producer()))

    输出:

    '''
    <class 'function'>
    <class 'generator'>
    
    '''
  • 相关阅读:
    前端 JavaScript&Dom
    前端 css续
    前端 初级篇(CSS)
    前端 初级篇(HTML)
    堡垒机
    Python操作RabbitMQ
    常用到代码片段
    关于文件上传功能的思考
    JS正则表达式将url转成json格式
    一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
  • 原文地址:https://www.cnblogs.com/lumaoxin/p/6931195.html
Copyright © 2011-2022 走看看