Python中 yield的作用
flyfish
在英语中,yield 有“产生”、“产出”、“让出”等含义。在 Python 中,yield 的作用与这些含义相符。
当生成器函数执行到 yield 语句时,它会“产生”一个值并暂停执行,等待下一次调用。这与“产出”和“让出”控制权的概念一致。
生成器函数通过 yield 语句逐步生成值,而不是一次性返回所有值,这符合“产生”和“逐步提供”的概念。
yield 这个关键字,是为了明确表示生成器函数的特殊行为,即在生成值的同时保留状态,以便在后续调用中继续执行。
生成器函数
yield
最主要的功能是定义生成器函数。生成器函数在每次调用 next()
或在 for
循环中迭代时,从上次暂停的地方继续执行,直到遇到下一个 yield
语句。这种方式使得生成器能够逐步生成值,而不是一次性生成所有值,从而大大节省了内存资源。
def simple_generator():yield 1yield 2yield 3gen = simple_generator()
print(next(gen)) # 输出: 1
print(next(gen)) # 输出: 2
print(next(gen)) # 输出: 3
这段代码展示了生成器的基本用法。通过 yield
,我们可以在函数内部保存状态,并在每次调用时恢复执行,从而实现了高效的值生成机制。
节省内存
生成器的一个显著优点是其能够节省内存。在处理大规模数据集时,生成器可以逐步生成值,而不需要将所有数据一次性加载到内存中。这在处理大数据或无限序列时尤为重要,可以显著提高程序的性能和效率。
def large_range(n):for i in range(n):print(i)yield ifor i in large_range(9):if i % 3== 0:print("-----")
输出
0
-----
1
2
3
-----
4
5
6
-----
7
8
惰性求值
生成器支持惰性求值(lazy evaluation),即值只有在需要时才会计算。这一特性在处理复杂或昂贵的计算时特别有用,可以显著提高程序的性能。
def expensive_computation(values):for value in values:result = value * valueyield resultfor result in expensive_computation(range(5)):print(result)
输出
0
1
4
9
16
这里,expensive_computation
生成器在每次迭代时才计算平方值,而不是一次性计算所有值,从而节省了计算资源。
协程
生成器还可以用于实现协程(coroutine)。协程是一种更高级的生成器,可以通过 yield
语句接收外部输入,实现双向通信。这使得协程在处理异步任务和事件驱动编程中非常有用。
def coroutine_example():while True:x = yieldprint(f"Received: {x}")coro = coroutine_example()
next(coro) # 预激协程
coro.send(10) # 发送值给协程
coro.send(20) # 再次发送值
输出
Received: 10
Received: 20
在这个例子中,coroutine_example
生成器通过 yield
接收外部输入,并在每次接收到值时打印出来。这种双向通信的能力使得协程在复杂的应用场景中具有强大的灵活性。
异步生成器
在异步编程中,可以使用 async def
定义异步生成器,并用 yield
语句生成值。异步生成器可以与 async for
一起使用,从而实现高效的异步数据处理。
import asyncioasync def async_generator():for i in range(5):await asyncio.sleep(1) # 模拟异步操作yield iasync def main():async for value in async_generator():print(value)asyncio.run(main())
输出
0
1
2
3
4
使用异步生成器处理异步任务。通过 await
和 yield
的结合,异步生成器能够在异步操作之间高效地生成值。