Python 的 yield 表达式
Posted on Wed, 25 Dec 2024 16:11:20 +0800 by LiangMingJian
Python 的 yield 表达式
yield 表达式
当用户在一个函数体内使用 yield 表达式,那么这个函数会变成一个生成器函数。
def gen(): # 定义一个生成器函数
yield 123
生成器(generator)函数是用来返回一个生成器迭代器(generator iterator)对象的函数。
生成器迭代器要求程序在执行到每个 yield 时,临时暂停处理过程,并记住执行状态(包括局部变量和挂起的 try 语句),同时将一个值通过 yield 返回,最后等待用户唤醒程序,继续执行。当程序继续执行时,如果再次遇到 yield,则重复暂停操作,重新等待运行。
用户可以通过 next() 函数来恢复生成器的运行,重新运行后,与普通函数不同,生成器函数会从暂停位置继续执行,而不是从新开始。
**特别注意,生成器函数的启动也需要使用 next() 函数。 **
比如下述代码,生成器函数通过 next() 启动,当执行到第一个 yield 时,暂停程序,然后返回一个值。当再次通过 next() 启动时,程序不是从头开始的,而是从上次暂停的 yield 后继续执行,以此往复。
def func():
print("程序开始...")
yield 1
print("程序继续...")
yield 2
print("程序结束...")
yield 3
foo = func()
print(next(foo)) # 输出:程序开始... 和 1
print(next(foo)) # 输出:程序继续... 和 2
print(next(foo)) # 输出:程序结束... 和 3
拓展阅读:为什么需要 yield?
yield 能通过状态保持和暂停恢复的特性,在大型文件处理,流式数据处理,无限序列循环的过程中分段分批次读取或处理数据,显著的优化内存,提高程序效率。
比如在循环 for i in range(1000) 中,由于 range 会根据实参生成一个给定长度列表,当 range 的长度很大时,程序的内存占用也就很高,极其容易造成资源的浪费。
如果使用 yield 生成 generator iterator 迭代对象,则不会出现这个问题。
比如下述代码,程序通过 yield 保持每次循环状态,并返回数据,不需要在一开始生成一个大内存的列表,只占用 temp 这一个变量的内存,内存占用极小:
def func():
temp = -1
while temp < 1000:
temp += 1
yield temp
foo = func()
print(next(foo)) # 返回 0
print(next(foo)) # 返回 1
print(next(foo)) # 返回 2
————————————