yield函数

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

带有 yield 的函数不再是一个普通函数,而是一个生成器generator,

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.]))

猜你喜欢

转载自blog.csdn.net/weixin_38145317/article/details/88711458