zoukankan      html  css  js  c++  java
  • python中yield用法详解

          今天看python学习视频学到生成器这一块时始终弄不懂yield的用法及其原理,在网上详细查看yield的用法之后总结一下yield的使用方法。

          先看一个简单的yield语句:

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b
            n = n + 1

          这是有关斐波那契数列的一个函数,当时正是这个函数中的yield使我困惑导致整个函数不能理解。这个函数包含yield,实际上这已经是一个生成器(generator)了,这与普通的函数有很大的不同。

    def h():
        print 'hello'
        yield 6
    h()

          可以看到,调用h()之后,print 语句并没有执行!这就是yield,那么,如何让print 语句执行呢?这就是后面要讨论的问题,通过后面的讨论和学习,就会明白yield的工作原理了。

    2. yield是一个表达式

          Python2.5以前,yield是一个语句,但现在2.5中,yield是一个表达式(Expression),比如:

          x = yield 6

    表达式(yield 6)的返回值将赋值给x,所以,认为 x = 5 是错误的。那么如何获取(yield 5)的返回值呢?需要用到后面要介绍的send(msg)方法。

    3. 透过next()语句看原理

          现在,我们来揭晓yield的工作原理。我们知道,我们上面的h()被调用后并没有执行,因为它有yield表达式,因此,我们通过next()语句让它执行。next()语句将恢复Generator执行,并直到下一个yield表达式处。比如:

    def h():
        print('hello')
        yield 6
        print('python!')
    c = h()
    c.__next__()       #这里是双下划线

          c.next()调用后,h()开始执行,直到遇到yield 6,因此输出结果:

          hello

    当我们再次调用c.next()时,会继续执行,直到找到下一个yield表达式。由于后面没有yield了,因此会拋出异常:

    hello
    Traceback (most recent call last):
    python!
      File "C:/Users/zxj/PycharmProjects/firstProject/day4/test.py", line 29, in <module>
        c.__next__()
    StopIteration

    4. send(msg) 与 next()

          了解了next()如何让包含yield的函数执行后,我们再来看另外一个非常重要的函数send(msg)。其实next()和send()在一定意义上作用是相似的,区别是send()可以传递yield表达式的值进去,而next()不能传递特定的值,只能传递None进去。因此,我们可以看做

    c.next() 和 c.send(None) 作用是一样的。

    来看这个例子: 

    def h():
        print('hello'),
        x = yield 6
        print m
        y = yield 23
        print 'python'
    c = h()
    c.__next__()  #相当于c.send(None)
    c.send('ok')  #(yield 6)表达式被赋予了'ok'

    输出的结果为:

    hello

    ok

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

    5. send(msg) 与 next()的返回值

          send(msg) 和 next()是有返回值的,它们的返回值很特殊,返回的是下一个yield表达式的参数。比如yield 6,则返回 6 。到这里,是不是明白了一些什么东西?我们再延续上面的例子:

    def h():
        print('hello')
        x = yield 6
        print(m)
        y = yield 23
        print (y)
    c = h()
    x = c.__next__()  #x 获取了yield 6 的参数值 6
    y = c.send('ok')  #y 获取了yield 23 的参数值23
    print(x,y)

          输出结果:

    hello
    ok
    6 23

          以上就是python中有关yield用法方面的总结,如有不对的地方或者不全面的地方欢迎大家批评指正!!!

  • 相关阅读:
    js post 异步请求
    Android 实现文件上传功能(upload)
    js 金额文本框实现代码
    纯CSS画的基本图形(矩形、圆形、三角形、多边形、爱心、八卦等)
    NBearV2视频教学系列总索引,欢迎多提意见和建议[09/21更新至IoC篇]
    1.2 实体实例化及使用自定义实体[发布时间:9/6]
    NBear视频 4.1 基于NBear.IoC的企业级系统构架[发布时间:9/21]
    2.1 基于NBear.Data的实体持久化[发布时间:9/10]
    NBear案例源码 简易AJAX留言板 [Updated 10/31 Powered by NBear V3.0.0 preview]
    全面解析ASP.NET2.0下的URL重写
  • 原文地址:https://www.cnblogs.com/zhengxunjie/p/10622324.html
Copyright © 2011-2022 走看看