You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何捕获内部异常?嵌套异常的处理方法

在Python里处理这种由其他异常触发的内部异常(也就是链式异常)其实很简单,核心是利用异常对象的几个特殊属性来追踪到内部的原始异常。我给你拆解两种常见场景,再配上代码示例,你一看就懂:

1. 主动关联的异常(使用raise ... from ...)

如果你是在代码里明确用raise 外层异常 from 内部异常的方式抛出的,那外层异常对象会有一个__cause__属性,直接指向触发它的内部异常。

比如下面这个例子:

def process_data(data):
    try:
        int(data)
    except ValueError as inner_exc:
        # 主动把内部异常作为外层异常的原因抛出
        raise RuntimeError("处理数据失败") from inner_exc

try:
    process_data("not_a_number")
except RuntimeError as outer_exc:
    print(f"捕获到外层异常: {outer_exc}")
    # 获取内部异常
    inner_exc = outer_exc.__cause__
    if inner_exc:
        print(f"触发它的内部异常: {type(inner_exc).__name__}: {inner_exc}")
        # 在这里执行你针对内部异常的操作,比如记录日志、修复逻辑等
        # 比如:log_error(f"内部异常详情: {inner_exc}")
2. 隐式触发的异常(自动上下文)

有时候你并没有主动用from关联,但在处理一个异常的过程中又抛出了新的异常,这时候Python会自动把之前的异常存在新异常的__context__属性里。

举个例子:

def process_data(data):
    try:
        int(data)
    except ValueError:
        # 这里没有用from,属于隐式触发
        raise RuntimeError("处理数据失败")

try:
    process_data("not_a_number")
except RuntimeError as outer_exc:
    print(f"捕获到外层异常: {outer_exc}")
    # 获取内部异常(上下文异常)
    inner_exc = outer_exc.__context__
    if inner_exc:
        print(f"触发它的内部异常: {type(inner_exc).__name__}: {inner_exc}")
        # 执行你的内部异常操作
3. 通用遍历:处理所有链式异常

如果不确定异常是主动关联还是隐式触发的,你可以写一个简单的循环,遍历所有关联的异常,确保不会漏掉任何内部异常:

def handle_chain_exceptions(exc):
    current_exc = exc
    while current_exc:
        print(f"异常: {type(current_exc).__name__}: {current_exc}")
        # 在这里针对当前异常执行操作
        # 切换到下一个关联的异常
        current_exc = current_exc.__cause__ or current_exc.__context__

try:
    process_data("not_a_number")
except RuntimeError as outer_exc:
    handle_chain_exceptions(outer_exc)

额外提醒:__cause__是你主动用from设置的,优先级比__context__高;而__context__是Python自动帮你记录的上下文异常,当没有__cause__的时候才会用到。

内容的提问来源于stack exchange,提问作者Albert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:32:50