Python 3.11中如何为异常添加上下文备注信息_使用add_note方法
add_note方法仅在Python 3.11+中可用,且仅适用于Exception子类;它为异常添加人类可读备注,不改变异常类型、消息或传播逻辑,需在抛出前调用,多次调用会按序追加并以换行分隔。
add_note方法只在Python 3.11+可用,且仅对Exception子类有效
add_note 是 Python 3.11 引入的新方法,用于为异常对象附加人类可读的备注信息,它不会影响异常类型、消息或回溯链,只是额外挂载一段字符串。注意:它**不能**被调用在 BaseException 的非 Exception 子类上(比如 SystemExit、KeyboardInterrupt),否则会抛出 AttributeError。
常见错误现象:AttributeError: 'SystemExit' object has no attribute 'add_note' —— 这不是 bug,是设计限制。
- 仅适用于继承自
Exception的异常(如ValueError、RuntimeError、自定义异常) - 必须在异常实例化后、抛出前调用,抛出后无法再修改(因为异常对象通常被冻结在 traceback 中)
- 多次调用
add_note会按顺序追加,内容用换行分隔
如何正确添加多条备注并观察输出效果
备注本身不自动显示在默认 traceback 中,只有在显式打印异常、或使用 traceback.print_exception 等工具时才会呈现(Python 3.11+ 默认格式已支持)。直接 raise 后终端看到的 traceback 末尾会多出 Notes: 区块。
try:
raise ValueError("invalid input")
except ValueError as e:
e.add_note("来源:用户上传的CSV第42行")
e.add_note("建议:检查字段类型是否匹配schema")
raise
运行后 traceback 末尾会出现:
Python 3.14.3
微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。
Notes: 来源:用户上传的CSV第42行 建议:检查字段类型是否匹配schema
- 备注内容不参与
str(e)或e.args,所以print(e)不会显示它 - 若用
logging.exception()记录,Python 3.11+ 的默认 handler 会包含Notes:;旧版 logging 需手动提取e.__notes__ -
e.__notes__是只读列表,不可直接赋值,只能通过add_note添加
与__cause__和__context__的本质区别
add_note 和异常链(__cause__ / __context__)解决的是不同问题:后者表达「这个异常是怎么来的」,前者表达「这个异常需要你注意什么」。它们互不干扰,可以共存。
-
raise new_exc from old_exc设置__cause__,影响 traceback 的The above exception was the direct cause of the following exception提示 -
add_note只增加说明文字,不改变异常传播逻辑或嵌套结构 - 调试时,
__notes__更适合放临时诊断线索(如“此时 cache_size=128”),而__cause__应严格用于真实因果链
生产环境使用时容易忽略的兼容性陷阱
如果你的代码需支持 Python add_note 会导致 AttributeError。不能靠 hasattr(e, 'add_note') 安全兜底——因为旧版本异常对象确实没有该方法,但检查后调用仍可能失败(比如在 except 块外捕获到异常再处理)。
- 推荐做法:封装一个兼容函数,例如
safe_add_note(exc, note),内部用sys.version_info >= (3, 11)判断 - 不要依赖
__notes__做逻辑分支(比如 if len(e.__notes__) > 0),它在旧版本不存在,访问会报错 - 单元测试中若 mock 异常,需确保 mock 对象也实现了
add_note方法,否则测试在 3.11 环境下会失败
真正要用好 add_note,得记住它不是“更漂亮的 message”,而是独立于异常语义的诊断附言——写的时候想清楚:这段话是给未来查问题的人看的,不是给程序逻辑读的。
如非特殊说明,本站内容均来自于网友自主分享,如有任何问题均请联系我们进行处理!
猜您喜欢
Claude长文本处理提示词怎么写才能保持上下文一致
2026-06-28你是一位专为嵌入式C项目做静态分析的技术写作助手,当前处理STM32F407平台,使用IAR8.50.9编译器。【禁止生成未加volatile修饰的寄存器指针;禁止省略中断向量表偏移校验步骤;禁止使用C11标准以外的语法特性】 你想让claude在处理长文档时始终记住角色设定、技术约束和输出格式,而不是到第三轮就忘了自己是嵌入式c工程师、漏掉volatile修饰要求、把中断向量表校验步骤一笔带过。...
MiMo Code 项目记忆:AI 编程如何通过记忆克服短期上下文疲劳
2026-06-28MiMoCode通过结构化项目记忆(MEMORY.md)、检查点重建、自动蒸馏和编辑闭环,解决AI编程的短期上下文疲劳。它将架构决策、模块边界、技术约束、数据契约作为强制校验规则,实现记忆继承、自我进化与深度编码协同。 ☞☞☞AI智能聊天,问答助手,AI智能搜索,多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜ AI编程的“短期上下文疲劳”,本质不是模型不够聪明,而是它被锁在一次对话、一个窗口、一...
MiMo Code 项目记忆实现:AI 开发助手如何记住代码的运行上下文
2026-06-28MiMoCode的项目记忆存于四个文件:MEMORY.md(项目规则与架构决策)、checkpoint.md(会话状态快照)、notes.md(临时笔记)、tasks//progress.md(任务进度日志),均位于.mimo/memory目录下。 ☞☞☞AI智能聊天,问答助手,AI智能搜索,多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜ MiMoCode的项目记忆不是靠模型“硬记”,而是用工程...
MiMo Code 项目记忆管理:AI 编程代理如何避免上下文冗余
2026-06-28MiMoCode通过工程化分层记忆管理提升AI效率:项目记忆提取稳定信息,会话检查点存档关键节点,任务进度追踪记录执行状态;动态简报替代全量回放,定期/dream指令收敛优化记忆,支持用户主动查看、删除或更新记忆。 ☞☞☞AI智能聊天,问答助手,AI智能搜索,多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜ MiMoCode的项目记忆管理不是靠模型“硬记”,而是用工程化方式把记忆从主任务流中剥离出...
MiMo Code 无限上下文技巧:AI 程序员如何自动总结与保存记忆
2026-06-28MiMoCode的“无限上下文”依靠自动化记忆协同机制实现,而非扩大模型窗口:Checkpoint在20%、45%、70%窗口使用率时自动触发,由Writer子Agent结构化归档关键信息;Rebuild机制在90%时生成精简上下文简报以续写;/dream每7天自动整合历史生成项目状态快照;notes.md为用户专属便签区,仅读权限保障系统一致性。 ☞☞☞AI智能聊天,问答助手,AI智能搜索,多模...
如何修复Python aiohttp请求时出现的ClientPayloadError?
2026-06-04ClientPayloadError表明服务端提前关闭连接,非客户端代码错误;常见于服务端超时、拒绝大响应或代理截断,需通过抓包、检查响应头、服务端日志及添加读取超时和异常处理来定位解决。 ClientPayloadError通常意味着服务端提前关闭了连接 这个错误不是客户端代码写错了,而是aiohttp在读取响应体时发现服务端已经断开了连接。常见于服务端超时、主动拒绝大响应、或代理/网关(如Ng...
如何使用Python监控服务器CPU温度并邮件告警_通过psutil模块读取系统信息
2026-06-04psutil无法直接读取CPU温度,因其依赖系统硬件接口且Linux需lm_sensors支持、Windows/macOS完全不支持;可靠方式是用subprocess调用sensors命令解析输出,并配合邮件告警与健壮性设计。 psutil本身不提供CPU温度读取功能——它无法直接获取温度传感器数据,强行调用psutil.sensors_temperatures()在多数Linux发行版(尤其是无...
如何在Python中验证文件的MD5校验和以确保数据完整性?
2026-06-04必须分块读取,推荐8192或65536字节块大小,以rb模式打开文件,循环调用update(),最后用hexdigest()获取32位小写十六进制字符串;校验时需strip().lower()统一格式并做长度校验。 用hashlib.md5()读取文件并计算校验和 直接调用hashlib.md5()并传入整个文件内容(比如md5.update(f.read()))在大文件上会爆内存。必须分块读取,...
怎样在Python Tkinter中使用线程池处理高并发的GUI数据更新?
2026-06-04不能直接用ThreadPoolExecutor更新Tkinter控件,因为Tkinter的Tcl解释器只允许主线程操作UI;子线程(包括线程池中的工作线程)调用widget方法会引发TclError或卡死;必须通过queue.Queue+root.after()将结果安全传回主线程更新。 为什么不能直接用concurrent.futures.ThreadPoolExecutor更新Tkinter控...
如何在Python 3中正确判断一个对象是否为某个类的实例?
2026-06-04应优先使用isinstance()而非type()做类型判断,因isinstance()遵循MRO、支持继承与ABC,体现鸭子类型哲学;type()仅判别直接类型,适用极少数需严格身份校验的场景。 用isinstance()而不是type() 直接比较type(obj)==SomeClass在绝大多数场景下是错的——它无法识别子类实例。比如isinstance(42,int)返回True,但typ...
