zoukankan      html  css  js  c++  java
  • 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() 的值,不仅代码简洁,而且执行流程异常清晰。

  • 相关阅读:
    Github开始强制使用PAT(Personal Access Token)了
    STM32F401的外部中断EXTI
    STM32F401的PWM输出
    STM32F103和STM32F401的ADC多通道采集DMA输出
    nRF24L01无线模块笔记
    51单片机(STC89C52)在Ubuntu下的开发
    51单片机(STC89C52)的中断和定时器
    51单片机的软件和硬件PCA/PWM输出
    Zadig 云原生持续交付 面向开发者设计的开源、高可用 CI/CD
    人生 乐观 悲观 英雄
  • 原文地址:https://www.cnblogs.com/sayiqiu/p/10788949.html
Copyright © 2011-2022 走看看