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

如何验证对象在Python任意版本中是否可被作为异常抛出?

如何验证一个对象是否可作为Python异常抛出?

我最近在项目中需要实现一个工具函数,用来判断给定的参数是否可以被当作异常抛出。最开始写了这样一段代码:

def is_raisable(exception):
    funcs = (isinstance, issubclass)
    return any(f(exception, BaseException) for f in funcs)

它能正确处理的场景

这个函数目前可以完美应对两种最常见的情况:

  • 检查异常类本身:is_raisable(KeyError) 返回 True,因为KeyError是BaseException的直接子类
  • 检查已经实例化的异常对象:is_raisable(KeyError("missing key")) 返回 True,因为该实例属于BaseException的子类实例

会失效的边缘场景

不过在一些特殊情况下,这个函数的判断会出错或者直接抛出错误:

  1. 抽象异常基类:如果传入一个继承自BaseException的抽象基类(ABC),函数会返回True,但实际上你无法实例化并抛出这个类——因为抽象基类要求必须实现抽象方法才能实例化:
    from abc import ABC, abstractmethod
    
    class AbstractAppError(BaseException, ABC):
        @abstractmethod
        def log_error(self):
            pass
    
    is_raisable(AbstractAppError)  # 返回True,但raise AbstractAppError()会触发TypeError
    
  2. 异常类型的元组:在try/except语句中,我们经常会用元组来指定多个要捕获的异常,但如果把这种元组传给is_raisable,函数会直接抛出TypeError——因为issubclass的第一个参数必须是类,不能是元组:
    is_raisable((KeyError, ValueError))  # 抛出TypeError: issubclass() arg 1 must be a class
    
  3. 动态修改的类:如果一个原本继承自BaseException的类被动态修改,移除了继承关系(虽然这种情况很少见),函数的判断结果会和实际可抛出性不一致。

简单的优化思路

如果要覆盖这些场景,可以对函数做一些调整:

  • 针对元组的情况,先判断输入是否是元组,然后递归检查每个元素是否可抛出
  • 针对抽象基类,可以额外检查该类是否可以被实例化(不过要注意,有些异常类实例化需要必传参数,这种检查可能会有局限性)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:30:02