生成器是协程调度的轻量载体,其对象封装代码对象、栈帧、指令偏移及执行上下文;yield 暂停保留局部变量,gi_frame.f_lasti 记录下条字节码;不可重入,StopIteration 后再调 next() 报 RuntimeError。
Python 生成器不是语法糖,是协程调度的轻量载体;不理解 yield 的状态机本质,就只能靠试错调 StopIteration。
调用含 yield 的函数时,Python 不执行函数体,而是立即返回一个 generator 对象。这个对象内部封装了:代码对象(__code__)、局部变量栈帧(gi_frame)、当前指令偏移(gi_running 和 gi_suspended 标志)、以及一个可恢复的执行上下文。
关键点:
gi_frame.f_lasti 记录下一条要执行的字节码位置,每次 next() 就从这里继续yield 暂停时,所有变量仍驻留在 gi_frame.f_locals 中StopIteration,gi_frame 被设为 None,再调 next() 必报 RuntimeError: generator already exhausted
yield 和 yield from 的行为差异yield 返回单个值并暂停;yield from 是委托协议,把子生成器的产出、异常传递和关闭信号全部代理出去。
常见误用场景:
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_re
ader("data.txt")
next(gen)
del gen # 不保证立刻触发 finally!依赖 GC,可能延迟甚至不触发
真正可靠的释放方式只有显式调用 close() 或用 with + 自定义上下文管理器包装生成器。
生成器天然适合建模状态流转:每个 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
# go
# 字节
# 栈
# 状态码
# 可迭代对象
# red
# elif
相关文章:
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
SQL查询语句优化的实用方法总结
制作网站的过程怎么写,用凡科建站如何制作自己的网站?
建站之星2.7模板快速切换与批量管理功能操作指南
php条件判断怎么写_ifelse和switchcase的使用区别【对比】
保定网站制作方案定制,保定招聘的渠道有哪些?找工作的人一般都去哪里看招聘信息?
网站专业制作公司有哪些,做一个公司网站要多少钱?
定制建站是什么?如何实现个性化需求?
音响网站制作视频教程,隆霸音响官方网站?
网站网页制作电话怎么打,怎样安装和使用钉钉软件免费打电话?
可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?
如何在万网自助建站中设置域名及备案?
如何快速重置建站主机并恢复默认配置?
如何快速生成可下载的建站源码工具?
武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?
如何选择PHP开源工具快速搭建网站?
Swift开发中switch语句值绑定模式
整人网站在线制作软件,整蛊网站退不出去必须要打我是白痴才能出去?
如何在云主机上快速搭建多站点网站?
建站三合一如何选?哪家性价比更高?
简历在线制作网站免费版,如何创建个人简历?
网站按钮制作软件,如何实现网页中按钮的自动点击?
电影网站制作价格表,那些提供免费电影的网站,他们是怎么盈利的?
简单实现Android验证码
,如何利用word制作宣传手册?
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
如何在阿里云香港服务器快速搭建网站?
如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?
内网网站制作软件,内网的网站如何发布到外网?
建站之星如何取消后台验证码生成?
如何在IIS中配置站点IP、端口及主机头?
香港服务器网站生成指南:免费资源整合与高速稳定配置方案
小建面朝正北,A点实际方位是否存在偏差?
建站主机助手选型指南:2025年热门推荐与高效部署技巧
宝塔新建站点报错如何解决?
定制建站策划方案_专业建站与网站建设方案一站式指南
定制建站流程解析:需求评估与SEO优化功能开发指南
c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】
子杰智能建站系统|零代码开发与AI生成SEO优化指南
唐山网站制作公司有哪些,唐山找工作哪个网站最靠谱?
建站之星图片链接生成指南:自助建站与智能设计教程
义乌企业网站制作公司,请问义乌比较好的批发小商品的网站是什么?
黑客如何利用漏洞与弱口令入侵网站服务器?
头像制作网站在线制作软件,dw网页背景图像怎么设置?
创业网站制作流程,创业网站可靠吗?
武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?
如何选择最佳自助建站系统?快速指南解析优劣
网站制作培训多少钱一个月,网站优化seo培训课程有哪些?
用v-html解决Vue.js渲染中html标签不被解析的问题
如何通过IIS搭建网站并配置访问权限?
*请认真填写需求信息,我们会在24小时内与您取得联系。