• Python yield


    yield用法

    带yield的函数其实是一个生成器,但为了好理解,不妨先把yield看成一个return,后面的语句暂时不执行

    e.g. 1

    def foo():
        print("starting...")
        while True:
            res = yield 4
            print("res:", res)
    
    g = foo()
    print(next(g))
    print("*" * 20)
    print(next(g))
    

    输出

    starting...
    4
    ********************
    res: None
    4
    

    程序开始执行后,因为foo()里面有yield关键字,所以先得到一个生成器g
    调用next(),foo()才真正执行,先打印出"starting...",进入while循环
    遇到yield,将其看做return 4,程序在此暂停,此时没有将4赋值给res,此时next(g)完成,即print(4)
    打印20个*
    又开始下面的next(),但这时候是从刚才暂停的地方开始执行,也就是要执行res的赋值操作,这时候要注意,此时res右边是没有值的,因为4已经return出去了,所以这个时候res赋值是None,将其打印出来之后,程序继续在while循环里执行,此时又碰到了yield,这时候同样return 4,print(4)

    小结:带yield的函数时一个生成器,这个生成器有一个next函数,next开始的地方是接着上一次next停止的地方

    e.g.2

    def foo():
        print("starting...")
        while True:
            res = yield 4
            print("res:", res)
    g = foo()
    print(next(g))
    print("*" * 20)
    print(g.send(7))
    

    输出

    starting...
    4
    ********************
    res: 7
    4
    

    为什么要用生成器

    用list会占用很多内存空间,而用yield

    def foo(num):
        print("starting...")
        while num<10:
            num += 1
            yield num
    
    for n in foo(0):
        print(n)
    
    # 也可以单步调试
    f = foo(0)
    next(f)
    next(f)
    

    简单地讲,yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 fab(5) 不会执行 fab 函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。

    结论:
    一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
    yield 的好处是显而易见的,把一个函数改写为一个 generator 就获得了迭代能力,比起用类的实例保存状态来计算下一个 next() 的值,不仅代码简洁,而且执行流程异常清晰。

  • 相关阅读:
    向Sql Server数据库插入中文时显示乱码的解决办法 (转)
    自定义控件开发知识点
    Win7旗舰版中的IIS配置asp.net的运行环境
    windows使用
    Visual Studio 2012自动添加注释(如版权信息等)
    3个线程彼此通知
    多线程12_张孝祥 java5读写锁技术的妙用
    多线程11_张孝祥 java5的线程锁技术
    Spring整合hibernate4:事务管理[转]
    HTML界面JQuery ajax 返回200,但走Error方法
  • 原文地址:https://www.cnblogs.com/sayiqiu/p/10788949.html
Copyright © 2020-2023  润新知