在 Python 中,yield 是用于定义生成器函数的关键字,其核心功能是暂停函数执行并返回一个值,同时保留函数状态以便后续恢复执行。以下是详细说明:
1. yield 的基本作用- 生成器函数:当函数中包含 yield 时,该函数会变为生成器函数。调用时不会立即执行,而是返回一个生成器对象(迭代器)。
- 暂停与恢复:每次执行到 yield 时,函数会暂停并返回 yield 后的值;下次调用时(如通过 next()),函数从暂停处继续执行。
def my_generator(): yield 1 # 第一次调用 next() 返回 1 yield 2 # 第二次调用 next() 返回 2 yield 3 # 第三次调用 next() 返回 3gen = my_generator() # 返回生成器对象print(next(gen)) # 输出: 1print(next(gen)) # 输出: 22. yield 的核心优势- 延迟计算:值在需要时才生成,适合处理大数据或无限序列(如实时数据流)。
- 内存高效:仅保存当前状态,而非全部数据。例如,逐行读取文件而非一次性加载。
- 支持迭代协议:可直接用于 for 循环,无需手动调用 next()。
# 示例:逐行读取大文件(节省内存)def read_large_file(file_path): with open(file_path) as file: for line in file: yield line # 每次返回一行,不占用全部内存for line in read_large_file("huge_log.txt"): process(line) # 按需处理每一行3. 从生成器获取值的常见方法- next() 函数:手动逐次获取值,触发 StopIteration 异常当无更多值时。
- for 循环:自动处理迭代终止,推荐日常使用。
- 转换为列表(谨慎使用):list(my_generator()) 会耗尽生成器,失去延迟加载优势。
# 使用 for 循环(推荐)for value in my_generator(): print(value) # 依次输出 1, 2, 3# 转换为列表(仅当数据量较小时)values = list(my_generator()) # [1, 2, 3]4. 高级用法- yield from:简化嵌套生成器的值传递(Python 3.3+)。
- 协程与状态保存:yield 可用于协程,实现更复杂的异步逻辑(需结合 send() 方法)。
# yield from 示例def sub_generator(): yield "A" yield "B"def main_generator(): yield from sub_generator() # 等价于逐个 yield "A", "B" yield "C"list(main_generator()) # 输出: ['A', 'B', 'C']总结- yield 的本质:将函数转换为生成器,实现惰性求值和状态保存。
- 适用场景:处理大规模数据、无限序列、流式处理或需要暂停/恢复的逻辑。
- 注意事项:生成器只能迭代一次,耗尽后需重新创建。
通过合理使用 yield,可以显著提升代码的内存效率和可读性,尤其在数据密集型任务中。