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)
相关推荐
梅雅达编程笔记8 小时前
编程启蒙|Scratch 转 Python 系列第9天:字典/哈希表积木双向对照(AI大模型参数配置表实战)
开发语言·人工智能·python·numpy·pandas
zhz52149 小时前
GIS项目中空间参考转换与MBTiles偏移:问题成因、解法与避坑
python·vue·gis
KaMeidebaby10 小时前
卡梅德生物技术快报|如何制备单克隆抗体:小众禽类靶点单抗制备实操流程:双载体抗原交叉筛选完整工艺记录
人工智能·python·深度学习·算法·机器学习
乱写代码10 小时前
Pydantic学习--BaseModel
python
fu159357456811 小时前
【边缘计算实战】P1:从零搭建边云任务卸载仿真实验台(Python 可复现)
数据库·python·边缘计算
蜡台11 小时前
通过Gradle脚本声明更改Java变量
android·java·开发语言·python·kotlin·gradle·groovy
智能体与具身智能12 小时前
TVA 本质内涵与核心特征(系列)
人工智能·python·智能体视觉
云雾J视界12 小时前
SST:高频变压器设计实战:铁氧体 vs 纳米晶 vs 非晶,磁性材料怎么选
python·acdc·dab·sst
第一程序员12 小时前
Rust trait 入门:把 AI 客户端抽象成可替换接口
python·rust·github
Ulyanov13 小时前
Python实现6-DOF刚体仿真器(下)——环境扰动与控制闭环
开发语言·python·算法·系统仿真·雷达电子对抗·导引头