yield关键字

yield 的作用

暂停并返回值: 当函数执行到 yield 语句时,会暂停当前函数的执行,并将 yield 后面的值返回给调用者。下次调用时,函数会从上次暂停的位置继续执行。

实现惰性求值: 生成器不会一次性生成所有数据,而是按需逐个生成,节省内存空间。

支持迭代协议: 包含 yield 的函数会自动变成生成器函数,返回一个生成器对象,该对象实现了迭代器协议(iter() 和 next() 方法)。

yield关键字和return一样会返回一个值,使用next获取返回值,如果可以返回值会报错。

复制代码
def foo():
    print("one")
    yield "one"
    print("two")
    yield "two"


if __name__ == '__main__':
    f = foo()
    print(f)
    print(next(f))
    print('----')
    print(next(f))
    print('----')
    print(next(f))

for为什么没有使用next(foo())也可以执行生成器?

在 Python 中,for 循环可以直接迭代生成器对象,而不需要显式调用 next() 函数。这是因为 for 循环内部已经实现了对生成器的自动迭代机制。

复制代码
def foo():
    print("one")
    yield "one"
    print("two")
    yield "two"


if __name__ == '__main__':
    f = foo()
    # print(f)
    # print(next(f))
    # print('----')
    # print(next(f))
    # print('----')
    # print(next(f))
    for i in f:
        print(i)

原因分析:

生成器的本质:

生成器是一个特殊的迭代器,它实现了 iter() 和 next() 方法。

当你调用 foo() 时,它返回一个生成器对象,而不是直接执行函数体中的代码。

for 循环的工作原理:

for 循环会自动调用生成器的 iter() 方法获取迭代器。

然后在每次循环中调用 next() 方法来获取下一个值,直到遇到 StopIteration 异常(即生成器耗尽)为止。

等价关系:

复制代码
   for i in foo():
       print(i)

实际上等价于以下手动调用 next() 的方式:

复制代码
   f = foo()
   try:
       while True:
           i = next(f)
           print(i)
   except StopIteration:
       pass

使用场景

当需要读取大文件时,一次性加载全部内容会导致内存溢出。解释:通过 yield 逐行读取文件内容,避免将整个文件加载到内存中。yield 的核心优势在于其惰性求值特性,适用于需要高效处理大量数据或动态生成数据的场景。

复制代码
def read_log(path):
    with open(path, 'r') as f:
        for line in f:
            yield line.strip()


def count_error():
    count = 0
    for log_line in read_log("a.log"):
        if "error" in log_line:
            print(log_line)
            count += 1
    return count


if __name__ == '__main__':
    number = count_error()
    print(number)
相关推荐
Y幽谷客40 分钟前
Python加载本地大模型(Qwen3.5 8B)
python·大模型
伞伞悦读1 小时前
【第36期】Python 目录与路径详解:pathlib、文件遍历、创建、复制、移动和删除风险
开发语言·python
线上放牧人2 小时前
Windows删除图标缓存
windows·python·pyqt
qq_5470261792 小时前
Python 变量和简单数据类型
python
智搜广告3 小时前
智搜广告:科技行业AI回答优化公司如何破局
大数据·python·elasticsearch·geo
IpdataCloud4 小时前
AI智能体调用工具怎么核验来源IP?归属地、网络类型与代理风险识别(含Python代码)
数据库·python·tcp/ip
2601_966949654 小时前
只拿到股票代码还不够:量化程序到底还需要哪些标的信息?——从数据建模开始理解股票元数据
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
蒸鱼Yuzheng4 小时前
Python 游戏测试开发怎么准备:日志解析、接口校验、并发与可维护性
自动化测试·python·测试开发·面试题·游戏测试
Ivanqhz4 小时前
BM1688 双核架构
python·深度学习·神经网络·cnn·mlir
Java后端的Ai之路5 小时前
Python进阶探索17 - Python中的深拷贝与浅拷贝
人工智能·python·ai·浅拷贝·深拷贝