Python 如何设计“可恢复”的异常?
技术百科
舞姬之光
发布时间:2026-01-21
浏览: 次 Python中无原生可恢复异常,但可通过自定义RetryableError类标记可重试错误,配合except块修复状态、重试机制(如装饰器)、上下文管理器资源清理,实现逻辑上的可恢复行为。
Python 中没有原生的“可恢复异常”类型,但可以通过设计自定义异常类、配合 try...except 与状态管理,实现逻辑上的“可恢复”行为——即异常发生后,程序能修正问题并重试,而非直接终止或跳过。
用自定义异常标记“可重试错误”
定义一个继承自 Exception 的基类(如 RetryableError),让调用方明确知道该异常允许且预期被恢复。它本身不带恢复能力,但起语义和分类作用。
- 避免与
ValueError、KeyError等通用异常混用,便于统一拦截 - 可附加字段,如
retry_after=2、recoverable=True,供上层决策 - 示例:
class NetworkTimeoutError(RetryableError): pass
在异常处理中主动恢复状态
“可恢复”的核心不在异常本身,而在 except 块里做了什么。常见做法包括重连、刷新凭证、清理缓存、切换备用资源等。
- 捕获自定义可重试异常后,执行修复动作(如
session.refresh_token()) - 修复完成后,可选择
contin重试循环,或显式调用原逻辑
ue
- 注意避免无限重试:应设最大重试次数或退避策略(如指数退避)
封装成带重试逻辑的函数或装饰器
把“抛出 → 捕获 → 恢复 → 重试”流程抽象出来,提升复用性。例如:
- 写一个
@retry_on(RetryableError, max_attempts=3)装饰器,内部自动捕获、调用恢复钩子、延迟重试 - 恢复钩子可以是传入的函数(如
on_retry=lambda: db.reconnect()) - 比裸写
try/except/while更清晰,也更容易测试和配置
配合上下文管理器控制资源生命周期
若异常涉及资源(如文件、连接、锁),需确保恢复前资源已安全释放或重置。
- 使用
with确保__exit__正常执行,避免残留状态干扰恢复 - 自定义上下文管理器可在
__exit__中判断是否为可恢复异常,并触发清理+预热操作 - 例如:网络请求上下文在捕获
NetworkTimeoutError后,自动关闭旧连接并新建一个
# python
# 封装
# while
# session
相关栏目:
<?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; ?>
】
相关推荐
- MAC怎么设置程序窗口永远最前_MAC窗口置顶插件
- Win11关机快捷键是什么_Win11快速关机方法
- Python函数接口稳定性_版本演进解析【指导】
- ACF 教程:如何正确更新嵌套在多层 Group
- Win11如何设置电源计划_Win11电源计划优化
- 如何在 Go 中高效缓存与分发网络视频流
- Win10怎样清理C盘浏览器缓存_Win10清理浏
- Windows10怎么查看硬件信息_Windows
- 如何使用Golang开发简单的聊天室消息存储_Go
- Win11怎么关闭用户账户控制UAC_Window
- 如何在包含多值的列中精准搜索指定演员?
- Win11怎么清理C盘系统错误报告_Win11清理
- Win11怎么关闭防火墙通知_屏蔽Win11安全中
- 新手学PHP架构总混淆概念咋办_重点梳理【教程】
- Go 中实现 Python urllib.quot
- 如何在JavaScript中动态拼接PHP的bas
- Python包结构设计_大型项目组织解析【指导】
- C#怎么使用委托和事件 C# delegate与e
- 如何使用Golang匿名函数_快速定义临时函数逻辑
- Golang如何遍历目录文件_Golang fil
- 如何在 Go 中正确反序列化 XML 多节点数组(
- Python对象比较排序规则_集合使用说明【指导】
- 如何在Golang中使用time处理时间_Gola
- Win10系统映像怎么恢复 Win10使用系统映像
- Mac电脑进水了怎么办_MacBook进水后紧急处
- Mac版Final Cut Pro入门_Mac视频
- 如何在Golang中处理二进制数据_Golang
- Mac如何设置动态壁纸?(让桌面动起来)
- php打包exe后无法读取环境变量_变量配置方法【
- Python网络超时处理_健壮性设计说明【指导】
- Windows10怎么备份注册表_Windows1
- VSC怎样在VSC中调试PHPAPI_接口调试技巧
- 如何使用Golang指针与接口结合_实现方法调用和
- 如何使用Golang构建简易投票统计功能_Gola
- 如何在Golang中实现并发消息队列消费者_Gol
- php删除数据怎么清空表_truncate与del
- Win11如何更改任务栏颜色 Win11自定义任务
- Win10怎样卸载TeamViewer_Win10
- Win11怎么更改电脑名称_Windows 11修
- Win10怎么创建桌面快捷方式 Win10为应用创
- c++的STL算法库find怎么用 在容器中查找指
- Python正则表达式实战_模式匹配说明【教程】
- 怎么将XML数据可视化 D3.js加载XML
- Python异步编程高级项目教程_asyncio协
- c++中的std::conjunction和std
- Win11如何隐藏桌面图标 Win11一键隐藏/显
- XAMPP 启动失败(Apache 突然停止)的终
- Win11如何更改用户账户文件夹名称 Win11修
- C++ STL算法库怎么用?C++常用算法函数(s
- Mac怎么进行语音输入_Mac听写功能设置与使用【


QQ客服