0

0

Python生成器系统学习路线第527讲_核心原理与实战案例详解【技巧】

冷炫風刃

冷炫風刃

发布时间:2025-12-29 21:14:02

|

251人浏览过

|

来源于php中文网

原创

生成器是协程调度的轻量载体,其对象封装代码对象、栈帧、指令偏移及执行上下文;yield 暂停保留局部变量,gi_frame.f_lasti 记录下条字节码;不可重入,StopIteration 后再调 next() 报 RuntimeError。

python生成器系统学习路线第527讲_核心原理与实战案例详解【技巧】

red">Python 生成器不是语法糖,是协程调度的轻量载体;不理解 yield 的状态机本质,就只能靠试错调 StopIteration

生成器对象到底在内存里存了什么

调用含 yield 的函数时,Python 不执行函数体,而是立即返回一个 generator 对象。这个对象内部封装了:代码对象(__code__)、局部变量帧(gi_frame)、当前指令偏移(gi_runninggi_suspended 标志)、以及一个可恢复的执行上下文。

关键点:

  • gi_frame.f_lasti 记录下一条要执行的字节码位置,每次 next() 就从这里继续
  • 局部变量不会被销毁——yield 暂停时,所有变量仍驻留在 gi_frame.f_locals
  • 生成器对象不可重入:一旦抛出 StopIterationgi_frame 被设为 None,再调 next() 必报 RuntimeError: generator already exhausted

yieldyield from 的行为差异

yield 返回单个值并暂停;yield from 是委托协议,把子生成器的产出、异常传递和关闭信号全部代理出去。

立即学习Python免费学习笔记(深入)”;

常见误用场景:

法语写作助手
法语写作助手

法语助手旗下的AI智能写作平台,支持语法、拼写自动纠错,一键改写、润色你的法语作文。

下载
  • 想用 yield from range(100000) 替代 for i in range(100000): yield i?可以,但注意:yield from 在 CPython 中有额外的帧切换开销,小数据量反而略慢
  • 子生成器抛异常时,yield from 会原样向上冒泡;而手动 for x in subgen(): yield x 会吞掉子生成器的 GeneratorExit
  • yield from 内部调用了 subgen().__iter__(),所以能委托任意可迭代对象(包括列表、文件对象),不只是生成器

生成器退出时的资源清理陷阱

生成器函数中用 try...finally 可以保证退出时执行清理逻辑,但必须注意触发时机:

def safe_reader(filename):
    f = open(filename)
    try:
        for line in f:
            yield line.strip()
    finally:
        print("file closed")
        f.close()

正常耗尽

gen = safe_reader("data.txt") list(gen) # → 打印 "file closed"

提前中断

gen = safe_reader("data.txt") next(gen) gen.close() # → 打印 "file closed"

但这样不行:

gen = safe_reader("data.txt") next(gen) del gen # 不保证立刻触发 finally!依赖 GC,可能延迟甚至不触发

真正可靠的释放方式只有显式调用 close() 或用 with + 自定义上下文管理器包装生成器。

用生成器实现有限状态机(FSM)的最小可行模式

生成器天然适合建模状态流转:每个 yield 是一个稳定状态,send() 是外部输入事件。

def traffic_light():
    state = "red"
    while True:
        cmd = yield state
        if state == "red" and cmd == "go":
            state = "green"
        elif state == "green" and cmd == "stop":
            state = "yellow"
        elif state == "yellow" and cmd == "stop":
            state = "red"

light = traffic_light() next(light) # 启动,输出 "red" print(light.send("go")) # → "green" print(light.send("stop")) # → "yellow" print(light.send("stop")) # → "red"

注意:send() 不能发给刚创建未启动生成器(需先 next()send(None)),否则报 TypeError: can't send non-None value to a just-started generator

这种写法容易忽略的是错误处理——没匹配的 cmd 会导致无限循环在当前状态,建议加默认分支抛异常或返回状态码

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

713

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

625

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

737

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

617

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1235

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

574

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

696

2023.08.11

俄罗斯搜索引擎Yandex最新官方入口网址
俄罗斯搜索引擎Yandex最新官方入口网址

Yandex官方入口网址是https://yandex.com;用户可通过网页端直连或移动端浏览器直接访问,无需登录即可使用搜索、图片、新闻、地图等全部基础功能,并支持多语种检索与静态资源精准筛选。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1

2025.12.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 2.5万人学习

SciPy 教程
SciPy 教程

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号