Python 的 yield 关键字是做什么的?

yield 把普通函数变成生成器函数:每次执行到 yield 产出一个值并暂停,下次迭代从暂停处继续,适合处理大数据集而无需全部载入内存。

最佳实践
Python 的 yield 关键字是做什么的?封面

一句话解释:yield 让函数变成"生成器"——调用它不立即执行函数体,而是返回一个可迭代对象;每次 next()(或 for 循环)执行到下一个 yield 吐出一个值并挂起,状态保留,下次继续。相比 return 一次给全部结果,yield 逐个产出、惰性计算,处理海量数据时内存友好。

先理解可迭代与生成器

列表是可迭代的,所有元素都在内存里:

nums = [1, 10, 100, 1000]
for i in nums:
    print(i)

生成器也是可迭代的,但元素是"现算现给"的,只能完整遍历一次:

gen = (x + 1 for x in range(4))  # 生成器表达式
for i in gen:
    print(i)

yield 的基本用法

def count_up_to(n):
    i = 1
    while i <= n:
        yield i   # 产出 i,函数在此挂起
        i += 1

for x in count_up_to(3):
    print(x)  # 依次输出 1、2、3

调用 count_up_to(3) 不会执行循环体,而是返回生成器对象;每次迭代推进到下一个 yield

典型场景:逐行处理大日志文件

def read_large_log(path):
    with open(path, encoding='utf-8', errors='replace') as f:
        for line in f:
            yield line.rstrip('\n')

for line in read_large_log('app.log'):
    if 'ERROR' in line:
        print(line)

几十 GB 的文件也能逐行处理,内存占用几乎恒定——这正是日志分析、ETL 场景最常见的写法。

进阶:yield 还能接收值

gen.send(value) 可以把值送回生成器内部(yield 表达式的返回值),这是协程的基础;日常数据处理中用得少,了解即可。

观测云对照

采集侧的惰性处理思想一致。 DataKit 采集日志采用流式读取、边采集边上报,不会把整个文件载入内存;你在自研采集脚本里用 yield 逐行产出,同样能实现稳定的低内存占用。

常见问题(FAQ)

Q:生成器能遍历多次吗?
A:不能。遍历完后生成器耗尽,再次迭代得到空结果;需要重新调用函数生成新的。

Q:yield 和 return 能同时出现在一个函数里吗?
A:可以。函数里出现 yield 就是生成器函数,此时 return 用于提前结束迭代(return 的值可通过 StopIteration 拿到)。

Q:yield from 是什么?
A:yield from 子生成器 用于把产出工作委托给另一个可迭代对象,等价于逐个 yield,写嵌套生成器时更简洁。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台