新闻详情

新闻详情

首页 / 资讯中心 / 详情

Python生成器与Yield机制详解及应用实践

发布时间:2026/9/16 16:49:25来源:尧图网络
Python生成器与Yield机制详解及应用实践
1. 生成器与Yield的底层机制Python生成器是一种特殊的迭代器其核心在于yield关键字实现的执行暂停与恢复机制。当函数包含yield语句时调用该函数不会立即执行代码而是返回一个生成器对象。这个对象遵循迭代器协议实现了__iter__()和__next__()方法。生成器函数执行到yield时会发生以下原子操作暂停函数执行保存当前栈帧包含局部变量、指令指针等将yield右侧表达式的值作为__next__()的返回值在下次调用__next__()时从保存的栈帧恢复执行def countdown(n): print(Starting countdown) while n 0: yield n n - 1 print(Blastoff!) # 生成器对象创建时不会执行函数体 gen countdown(3) print(next(gen)) # 输出: Starting countdown 然后输出 3 print(next(gen)) # 输出 22. 惰性求值的实现原理生成器通过延迟计算实现了内存高效的数据流处理。与列表等容器类型不同生成器不会预先生成所有元素而是在每次迭代时动态计算下一个值。关键特性对比特性列表生成器内存占用存储所有元素只存储当前状态计算时机立即计算按需计算可重用性可多次迭代单次迭代长度确定性已知长度可能无限典型应用场景处理大型文件时逐行读取生成无限序列如斐波那契数列数据管道中的中间处理环节# 文件处理对比 def read_lines_list(file): with open(file) as f: return f.readlines() # 立即读取所有行到内存 def read_lines_gen(file): for line in open(file): yield line # 每次迭代只读取一行3. 生成器表达式与语法糖生成器表达式是创建生成器的简洁语法形式为(expr for item in iterable)。与列表推导式不同它不会构建完整列表而是按需生成值。# 平方数生成器 squares (x*x for x in range(1000000)) # 不占用内存 sum_squares sum(x*x for x in range(1000000)) # 更高效的内存使用注意事项生成器表达式只能被消费一次避免在生成器表达式内修改外部变量复杂逻辑建议使用完整的生成器函数# 多层过滤示例 filtered ( x.upper() for x in open(data.txt) if not x.startswith(#) and len(x.strip()) 0 )4. 高级生成器控制方法除了基本的__next__()生成器还支持更精细的控制4.1 send()方法允许向生成器内部传递值该值会成为yield表达式的返回值def accumulator(): total 0 while True: value yield total if value is None: break total value gen accumulator() next(gen) # 启动生成器返回0 print(gen.send(1)) # 输出1 print(gen.send(5)) # 输出64.2 throw()方法向生成器内部抛出指定异常def resilient_gen(): try: while True: try: yield 42 except ValueError: print(Handled ValueError) except GeneratorExit: print(Cleaning up) gen resilient_gen() next(gen) # 返回42 gen.throw(ValueError) # 输出Handled ValueError并继续4.3 yield from语法PEP 380引入的语法用于简化生成器委托def chain(*iterables): for it in iterables: yield from it # 等价于 for item in it: yield item list(chain(ABC, range(3))) # [A,B,C,0,1,2]5. 生成器的实际应用模式5.1 协程模拟生成器可以用于实现简单的协程模式def coroutine(func): def start(*args, **kwargs): cr func(*args, **kwargs) next(cr) # 启动协程 return cr return start coroutine def grep(pattern): print(fLooking for {pattern}) while True: line (yield) if pattern in line: print(line) g grep(python) g.send(Yeah, but no, but yeah, but no) g.send(python generators rock!) # 会打印这行5.2 状态机实现生成器天然适合实现状态机def traffic_light(): while True: print(Red) yield print(Yellow) yield print(Green) yield light traffic_light() next(light) # Red next(light) # Yellow5.3 数据管道构建高效的数据处理管道def read_files(filenames): for name in filenames: with open(name) as f: yield from f def filter_comments(lines): for line in lines: if not line.strip().startswith(#): yield line def uppercase(lines): for line in lines: yield line.upper() pipeline uppercase(filter_comments(read_files([log1.txt, log2.txt]))) for line in pipeline: process(line)6. 性能优化与陷阱6.1 内存效率测试import sys from timeit import timeit # 列表推导式 list_comp [x*x for x in range(1000000)] print(f列表内存占用: {sys.getsizeof(list_comp)/1024/1024:.2f} MB) # 生成器表达式 gen_exp (x*x for x in range(1000000)) print(f生成器内存占用: {sys.getsizeof(gen_exp)} bytes) # 执行时间对比 print(列表构建时间:, timeit([x*x for x in range(1000000)], number10)) print(生成器构建时间:, timeit((x*x for x in range(1000000)), number10))6.2 常见陷阱与解决方案过早耗尽问题numbers (x for x in range(3)) print(sum(numbers)) # 6 print(sum(numbers)) # 0 (生成器已耗尽)变量作用域问题# 错误示例 gen (lambda: x for x in range(3)) print([g() for g in gen]) # 输出[2,2,2]而非[0,1,2] # 正确写法 gen (lambda xx: x for x in range(3))资源清理def read_db(): try: db connect_to_database() for record in db.query(): yield record finally: db.close() # 确保资源释放 # 使用contextlib.closing确保资源清理 from contextlib import closing with closing(read_db()) as gen: for item in gen: process(item)7. 异步生成器Python 3.6Python 3.6引入了异步生成器使用async for和await语法import asyncio async def async_counter(n): for i in range(n): await asyncio.sleep(1) yield i async def main(): async for i in async_counter(5): print(f{i} seconds passed) asyncio.run(main())关键区别使用async def定义包含yield和await必须使用async for迭代实现了__aiter__和__anext__方法
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Velero 开发指南:生成文件、代码检查、单元测试与依赖管理全流程 2026/9/16 17:31:32

Velero 开发指南:生成文件、代码检查、单元测试与依赖管理全流程

Velero 开发指南:生成文件、代码检查、单元测试与依赖管理全流程 【免费下载链接】velero Backup and migrate Kubernetes applications and their persistent volumes 项目地址: https://gitcode.com/GitHub_Trending/ve/velero Velero(README.m…

阅读更多 →
TypeScript编译速度优化实战指南 2026/9/16 17:31:32

TypeScript编译速度优化实战指南

1. TypeScript项目编译速度问题剖析每次保存文件后都要等上十几秒才能看到修改效果?一个中型项目的完整编译需要几分钟?作为从2014年就开始使用TypeScript的老司机,我见过太多团队在项目规模增长后陷入编译速度的泥潭。上周刚帮一个电商团队将…

阅读更多 →
在 macOS 上使用 Homebrew 搭建 Lean 4 源码编译环境:依赖安装与 CMake 配置实战 2026/9/16 17:31:32

在 macOS 上使用 Homebrew 搭建 Lean 4 源码编译环境:依赖安装与 CMake 配置实战

在 macOS 上使用 Homebrew 搭建 Lean 4 源码编译环境:依赖安装与 CMake 配置实战 【免费下载链接】lean4 Lean 4 programming language and theorem prover 项目地址: https://gitcode.com/GitHub_Trending/le/lean4 本文以仓库文档 doc/make/osx-10.9.md 为主…

阅读更多 →
GitNexus:零服务器代码知识图谱工具解析 2026/9/16 17:31:32

GitNexus:零服务器代码知识图谱工具解析

1. GitNexus项目概述GitNexus是一款面向开发者的零服务器知识图谱引擎,它能够自动分析代码仓库并构建可视化知识图谱。这个工具最吸引人的特点是完全基于浏览器运行,不需要任何服务器配置或后端知识,真正实现了开箱即用的代码理解体验。我在实…

阅读更多 →
Feast Feature Service(ADR-0001):为模型而生的检索级特征分组设计决策与源码实现剖析 2026/9/16 17:31:32

Feast Feature Service(ADR-0001):为模型而生的检索级特征分组设计决策与源码实现剖析

Feast Feature Service(ADR-0001):为模型而生的检索级特征分组设计决策与源码实现剖析 【免费下载链接】feast The Open Source Feature Store for AI/ML 项目地址: https://gitcode.com/GitHub_Trending/fe/feast 本文围绕 Feast 的架…

阅读更多 →
Layui表格行编辑实战:单元格编辑、数据源操作与批量保存 2026/9/16 17:28:32

Layui表格行编辑实战:单元格编辑、数据源操作与批量保存

简介:面向网页后台管理系统开发者,这份代码包聚焦 Layui 表格组件中的行级编辑与数据保存,能解决动态插入新行、触发编辑回填、删除记录并同步更新后端数据的常见问题,适合刚入门 Layui 或希望快速掌握表格交互语法的前端人员。资…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞