HOWTO · Python
如何在 Python 中打印异常
了解如何在 Python 中打印异常、选择错误消息或完整 traceback,并避免常见的异常处理错误。
本页内容
只需要错误消息时,请使用 print(exception)。需要包含错误文件和行号的完整 traceback 时,请在活动的 except 块中使用 traceback.print_exc()。应针对具体异常类型进行处理;需要保留的诊断信息应使用 logging,而不是 print()。
打印异常消息
将异常捕获为变量并传递给 print()。这是显示错误原因的最简方式:
try:
result = 10 / 0
except ZeroDivisionError as exc:
print("Could not calculate result:", exc)
输出:
Could not calculate result: division by zero
异常对象会被转换为消息文本。此示例只捕获 ZeroDivisionError,因此不容易隐藏无关的编程错误。如果多个错误需要相同处理,可以在元组中列出类型,例如 except (TypeError, ValueError) as exc:。
打印完整 traceback
消息不一定能说明错误的来源。导入 Python 内置的 traceback 模块,并在处理程序仍然活动时调用 print_exc():
import traceback
try:
values = [1, 2]
value = values[3]
except IndexError:
traceback.print_exc()
输出包含异常类型、消息、文件和失败的行。当异常来自多层嵌套的函数调用时,traceback 比单独的消息更有用。
print_exc() 读取当前正在处理的异常。在 except 块结束后调用,或在没有活动异常时调用,并不能恢复之前的 traceback;它可能输出 NoneType: None。请把调用保留在处理程序中,或保存异常后使用 print_exception() 进行明确控制。
显式控制 traceback 格式
traceback.print_exception() 接受异常对象,并可以写入指定的流。当需要格式化或重定向异常时很有用:
import sys
import traceback
try:
int("not a number")
except ValueError as exc:
traceback.print_exception(exc, file=sys.stdout)
要创建文本而不是立即打印,请使用 traceback.format_exception(exc):
import traceback
try:
raise RuntimeError("configuration is missing")
except RuntimeError as exc:
formatted = "".join(traceback.format_exception(exc))
print(formatted)
traceback 函数默认保留异常链。因此,raise ... from ... 链可以同时显示原始异常和新异常。只有在输出约定要求时才限制 traceback 或禁用异常链;删除上下文会使诊断更困难。
自定义异常和 logging
当调用方需要区分领域错误和内置错误时,请定义自定义异常。捕获该类型并以相同方式打印消息:
class ConfigurationError(Exception):
pass
try:
raise ConfigurationError("API key is missing")
except ConfigurationError as exc:
print("Configuration failed:", exc)
在应用或服务中,建议在处理程序内使用 logging.exception()。它会记录消息和活动 traceback,日志处理器还可以将其发送到文件或监控系统:
import logging
try:
load_settings()
except Exception:
logging.exception("Loading settings failed")
将 load_settings() 替换为可能失败的操作。示例在 logging 边界有意捕获宽泛的 Exception;普通应用逻辑应捕获自己确实能够处理的具体异常类型。
常见错误和 FAQ
- 不带类型的
except:也会捕获KeyboardInterrupt和SystemExit。除非有专门理由处理BaseException的子类,否则应避免使用。 - 当程序无法产生有效结果时,不要只打印通用消息然后静默继续。请重新引发异常,或返回明确的失败结果。
type(exc)显示具体类,str(exc)显示可读消息,repr(exc)可能提供更具诊断性的表示。- 如果输出要写入日志,请在处理程序内使用
logging.exception()。只需要简短交互式诊断时,print(exc)就足够了。 traceback.print_exc()用于当前正在处理的异常;保存异常对象并需要控制格式或输出时,traceback.print_exception(exc)更清晰。
这些模式使用 Python 内置的异常机制,不需要第三方包。应根据需要的是消息、完整调用路径、格式化文本还是持久应用日志来选择方法。