yield函数

yield是python的一个关键字,一个带有yield的函数就是一个生成器generator.当你使用一个yield的时候,对应的函数就是一个生成器了。生成器的功能就是在yield的区域进行迭代进行。

yield 是一个类似 return 的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。重点是:下一次迭代时,从上一次迭代遇到的yield后面的代码(下一行)开始执行。return 的作用:如果没有 return,则默认执行至函数完毕,返回的一 般是  yield的变量

在python的函数(function)定义中,只要出现了yield表达式(Yield expression),那么事实上定义的是一个generator function, 调用这个generator function返回值是一个generator。这根普通的函数调用有所区别,For example:

def gen_generator():
    yield 1


def gen_value():
    return 1

if __name__ == '__main__':
    ret = gen_generator()
    print(ret, type(ret))  # <generator object gen_generator at 0x7fa1e40dc150> <class 'generator'>
    ret = gen_value()
    print(ret, type(ret)) # 1 <class 'int'>

从上面的代码可以看出,gen_generator函数返回的是一个generator实例,generator有以下特别:

  • 遵循迭代器(iterator)协议,迭代器协议需要实现__iter__、next接口
  • 能过多次进入、多次返回,能够暂停函数体中代码的执行

  下面看一下测试代码

def gen_example():

    print ('before any yield')

    yield 'first yield'

    print ('between yields')

    yield 'second yield'

    print ('no yield anymore')


gen= gen_example()
gen.__next__()# 第一次调用显示 before any yield
gen.__next__() #第二次调用 显示 between yields
gen.__next__() #第三次调用 显示 no yield anymore
gen.__next__() # 这个时候函数已经调用完了,就会迭代结束,报错Traceback (most recent call last):
  # File "/home/jerry/PY_project/object_detect_factory/yolo/training/copyyyy.py", line 29, in <module>
  #   gen.__next__() #no yield anymore
# StopIteration

 调用gen example方法并没有输出任何内容,说明函数体的代码尚未开始执行。当调用generator的next方法,generator会执行到yield 表达式处,返回yield表达式的内容,然后暂停(挂起)在这个地方,所以第一次调用next打印第一句并返回“first yield”。 暂停意味着方法的局部变量,指针信息,运行环境都保存起来,直到下一次调用next方法恢复。第二次调用next之后就暂停在最后一个yield,再次调用next()方法,则会抛出StopIteration异常。 

调用gen example方法并没有输出任何内容,说明函数体的代码尚未开始执行。当调用generator的next方法,generator会执行到yield 表达式处,返回yield表达式的内容,然后暂停(挂起)在这个地方,所以第一次调用next打印第一句并返回“first yield”。 暂停意味着方法的局部变量,指针信息,运行环境都保存起来,直到下一次调用next方法恢复。第二次调用next之后就暂停在最后一个yield,再次调用next()方法,则会抛出StopIteration异常。 

  因为for语句能自动捕获StopIteration异常,所以generator(本质上是任何iterator)较为常用的方法是在循环中使用:

def generator_example():
    print('me')
    yield 1
    print('you')
    yield 2
    a=[4,5]
    b=[3,9,9]
    batch_size=8
    # yield tf.constant( [a, *b], np.zeros(batch_size))
    yield [a, b], np.zeros(batch_size)
    # yield [image_data, *y_true], np.zeros(batch_size)

if __name__ == '__main__':
    for e in generator_example():
        print(e)
        # me
        # 1
        # you
        # 2
        # ([[4, 5], [3, 9, 9]], array([0., 0., 0., 0., 0., 0., 0., 0.]))

 

  • 7
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
yield函数是Python中的一个关键字,用于定义生成器函数。生成器是一种特殊的迭代器,它可以通过yield语句来暂停和恢复函数的执行,从而实现按需生成数据的功能。 通过yield函数,我们可以将一个函数转化为生成器函数函数中包含yield语句的地方会被暂停执行,并返回一个值给调用者。当生成器函数再次被调用时,会从上次暂停的位置继续执行,直到再次遇到yield语句或函数结束。这种实现方式可以有效地节省内存,并提高性能。 下面以一个实例来详细说明yield函数的使用。 ``` def generate_numbers(n): i = 0 while i < n: yield i i += 1 numbers = generate_numbers(5) print(next(numbers)) # 输出:0 print(next(numbers)) # 输出:1 print(next(numbers)) # 输出:2 print(next(numbers)) # 输出:3 print(next(numbers)) # 输出:4 ``` 在这个例子中,generate_numbers是一个生成器函数。当调用它时,它会返回一个生成器对象。我们通过调用next()函数来获取生成器对象中的下一个值。每次调用next()函数时,函数会从yield语句处恢复执行,并返回yield关键字后的值。当生成器函数执行完毕时,通过调用next()函数会触发StopIteration异常。 通过这个例子,我们可以看到yield函数的实际应用:按需生成数据。在这个例子中,我们可以在使用generate_numbers函数时,只生成需要的数据,而不是一次性生成所有的数字。这样可以极大地节省内存,并提高程序的性能。 总的来说,yield函数的实例分析可以帮助我们更好地理解和使用生成器函数,从而在需要按需生成数据的场景下提供更加高效的解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值