format_exc() 更实用,因它返回字符串可存储、拼接、加前缀,而 print_exc() 仅输出到 stderr 且返回 None;应在 except 块中显式用 sys.exc_info() 获取异常,避免隐式调用出错。

直接用 traceback.format_exc(),它返回字符串形式的完整堆栈,适合记录或调试;别用 traceback.print_exc() 直接输出——它只打到 stderr,没法存、没法处理。
为什么 format_exc() 比 print_exc() 更实用
你在日志里想存异常详情,或者要发给监控系统,就必须拿到字符串。而 print_exc() 只是调用 sys.stderr.write(),不返回值,也没法插在 f-string 里拼接上下文。
-
format_exc()返回str,可赋值、可截断、可加前缀(比如加上请求 ID) -
print_exc()是“副作用函数”,返回None,误当返回值用会导致后续逻辑出错 - 两者都依赖当前线程最近一次未捕获的异常,但
format_exc()更可控——你可以在except块里明确调用,不会受其他线程干扰
在 except 块里正确获取当前异常堆栈
别依赖隐式异常状态。显式传入 sys.exc_info() 结果,才能确保拿到你 catch 到的那个异常,而不是被中间层覆盖掉的旧异常。
import sys import traceback <p>try: 1 / 0 except ZeroDivisionError:</p><h1>正确:显式绑定当前异常</h1><pre class="brush:php;toolbar:false;">exc_type, exc_value, exc_tb = sys.exc_info() tb_str = traceback.format_exception(exc_type, exc_value, exc_tb) full_trace = ''.join(tb_str) print(full_trace)
- 不用
format_exc()的隐式调用,避免多层except嵌套时拿错异常 -
format_exception()返回的是list[str],每行一个字符串,''.join()才是完整文本 - 如果只要最后一行错误信息(比如“ZeroDivisionError: division by zero”),用
traceback.format_exception_only(exc_type, exc_value)
自定义格式时注意 limit 和 chain 参数
默认会显示全部帧,但在生产环境可能太长;Python 3.12+ 还支持异常链(raise ... from),不设 chain=True 会漏掉根因。
-
traceback.format_exc(limit=5)只取最后 5 层调用帧,适合快速定位 -
traceback.format_exc(chain=False)关闭异常链展开,避免把During handling of the above exception...那段冗余信息也打出来 - 如果用了
raise new_exc from original_exc,且想保留原始异常上下文,必须保持chain=True(默认值)
真正容易被忽略的是:traceback 模块本身不捕获异常,它只是格式化器。如果你在 except 外调用 format_exc(),很可能返回空字符串或上一个异常的残留信息——务必确认调用位置在异常处理上下文中。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











