如何让生成器支持 throw() 抛异常到生成器内部
技术百科
舞夢輝影
发布时间:2026-01-27
浏览: 次 只有含yield表达式(如received = yield value)的生成器才能用throw()触发except捕获;yield语句无法中断执行,throw()将直接终止生成器。
生成器必须用 yield 表达式而非 yield 语句
Python 中,只有函数体内包含 yield 表达式(即出现在等号右侧、能接收值的 yield),才能通过 throw() 向内部抛异常并被 except 捕获。如果只写 yield 语句(如 yield 42),它仍可迭代,但 throw() 只会终止生成器,无法进入 except 块。
常见错误现象:Generator.throw() 调用后直接抛出 StopIteration 或原异常未被捕获,本质是控制流没停在可中断的 yield 表达式上。
- 正确写法:
received = yield value—— 此处yield是表达式,暂停点可接收值或异常 - 错误写法:
yield value(无赋值)—— 控制流经过即继续,throw()无法“插入”到执行中 - 即使不打算接收值,也应写成
_ = yield value或yield value; continue后补一个空yield表达式
throw() 必须在生成器暂停时调用
throw() 不是“发消息”,而是向当前暂停点注入异常。若生成器已结束(StopIteration 已 raise)、尚未启动(还没第一次 next() 或 send(None)),或正在运行中(比如卡在某个循环里没遇到 yield),调用 throw() 都会报 RuntimeError: generator already executing 或直接失败。
使用场景:常用于协程式状态机,比如等待用户输入时,外部想强制中断并清理资源。
- 首次启动必须用
next(gen)或gen.send(None),否则throw()无效 - 每次
throw()后,生成器必须再次被驱动(next()或send()),否则停留在抛异常后的暂停点 - 若生成器在
try/finally中,throw()
触发异常时
finally仍会执行
异常类型需与 except 匹配,且不能跳过 yield
生成器内 except 能捕获 throw() 的异常,前提是该 except 所在的 try 块覆盖了当前 yield 表达式所在的位置,并且异常类型一致。Python 不支持“跳转式捕获”——异常不会向上越过未激活的 try 块。
参数差异:gen.throw(TypeError, "msg") 等价于 gen.throw(TypeError("msg")),但推荐传入已实例化的异常对象,避免某些版本兼容问题。
- 若
yield在try外,throw()会直接冒泡,不会进except -
except BaseException:可捕获所有,但会吞掉GeneratorExit和SystemExit,慎用 - 捕获后若不
return或yield,生成器立即结束;若继续yield,则恢复迭代流程
实际例子:带错误恢复的计数生成器
下面是一个能响应 throw(ValueError) 并重置计数的生成器:
def counter():
i = 0
while True:
try:
i += 1
# 必须是 yield 表达式,哪怕不接收值
_ = yield i
except ValueError:
print("resetting...")
i = 0
调用方式:
g = counter()next(g) # → 1next(g) # → 2g.throw(ValueError) # 打印 resetting...,不抛异常next(g) # → 1(已重置)
容易踩的坑:忘记在 throw() 后调用 next() 或 send(),结果生成器停在 except 块末尾,下一次 next() 才真正产出值——这个延迟行为常被忽略。
# ai
# 是一个
# 出现在
# python
# 首次
# 跳转
# 迭代
# 还没
# 只会
# 不支持
# 循环
# 对象
# try
# throw
# 会报
# finally
# continue
# 停在
# raise
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win11声音忽大忽小怎么办 Win11音频增强功
- Golang如何实现基本的用户注册_Golang用
- 如何在网页无标准表格标签时高效提取结构化数据
- Win11无法安装软件怎么办_Win11解除应用安
- Win11怎么开启剪贴板历史记录_Windows1
- 如何在Golang中写入JSON文件_保存结构体数
- Windows 11怎么更改锁屏超时时间_Wind
- Windows10怎样设置家长控制_Windows
- Win11怎么更改系统语言_Win11中文语言包下
- Windows10系统怎么查看CPU核心数_Win
- Win11怎么设置触控板手势_Windows11三
- Linux如何使用Curl发送请求_Linux下A
- php删除数据怎么软删除_添加is_del字段标记
- c++ atoi和atof函数用法_c++字符数组
- 如何使用Golang写入二进制文件_Golang
- Win11怎么查看电脑配置_Win11硬件配置详细
- Python函数接口文档化_自动化说明【指导】
- Drupal 中 HTML 链接被双重转义导致渲染
- Windows10系统怎么查看设备管理器_Win1
- Python随机数生成_random模块说明【指导
- Win10如何更改网络连接_Windows10以太
- Mac怎么安装软件_Mac安装dmg与pkg文件的
- 如何使用正则表达式精确匹配最多含一个换行符的 st
- VSC怎样用终端运行PHP_命令行执行脚本的步骤【
- 如何在Golang中实现自定义Benchmark_
- php会话怎么开启_session_start函数
- 如何使用Golang table-driven基准
- Mac如何调整Dock栏大小和位置_Mac程序坞个
- c++怎么调用nana库开发GUI_c++ 现代风
- 如何使用Golang优化模块引入路径_Golang
- PythonGIL机制理解_多线程限制解析【教程】
- Win11怎么更改系统语言为中文_Windows1
- MySQL 中使用 IF 和 CASE 实现查询字
- c++怎么使用类型萃取type_traits_c+
- c++20的std::format怎么用 比pri
- Win11怎么禁用键盘自带键盘_Win11笔记本禁
- Python正则表达式实战_模式匹配说明【教程】
- Win11声音太小怎么办_Windows 11开启
- c++ std::atomic如何保证原子性 c+
- Windows如何拦截2345弹窗广告_Windo
- Go 语言标准库为何不提供泛型 Contains
- 如何减少Golang内存碎片化_Golang内存分
- MAC怎么截图并快速编辑_MAC自带截图快捷键与标
- 如何在Golang中捕获JSON序列化错误_Gol
- Windows10怎么卸载预装软件_Windows
- Python技术债务管理_长期维护解析【教程】
- Win11如何设置文件关联 Win11修改特定文件
- Python如何创建带属性的XML节点
- MAC怎么使用表情符号面板_MAC Emoji快捷
- Windows10怎样连接蓝牙设备_Windows


QQ客服