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

如何实现支持多异常转换的带参数类方法装饰器?

问题

现有类方法evaluate执行时若计算结果过大会抛出OverflowError,可以用overflow_adapter装饰器将其转换为ValueError抛出。现在需要实现一个带参数的exception_adapter装饰器,支持指定需要捕获的异常列表(通过aware参数)以及要抛出的目标异常(通过response参数)。以下是未完成的代码,请补全使其正常工作:

def evaluate(self): return self.left ** self.right
def overflow_adapter(method):
    def wrapper(self):
        try:
            return method(self)
        except OverflowError:
            raise ValueError("Result is too big!")
    return wrapper

@overflow_adapter
def evaluate(self): return self.left ** self.right
@exception_adapter(aware=[OverflowError,], response=ValueError("Result is too big!"))
def evaluate(self): return self.left ** self.right
def exception_adapter(...):
    def wrapper(...):
        try:
            return method(self)
        except BaseException as e:
            if e in aware: raise response
    return wrapper

解答

带参数的装饰器需要三层嵌套结构:外层函数接收装饰器的参数,中层函数接收被装饰的方法,内层是实际执行的包装函数。同时需要修正异常判断的逻辑(直接用e in aware无法正确匹配异常实例和异常类的关系),补全后的代码如下:

def exception_adapter(aware, response):
    def decorator(method):
        def wrapper(self, *args, **kwargs):
            try:
                return method(self, *args, **kwargs)
            except BaseException as e:
                if isinstance(e, tuple(aware)):
                    # 若需要保留原异常上下文,可使用 raise response from e
                    raise response
        return wrapper
    return decorator

关键点说明:

  • 三层结构:exception_adapter先接收aware和response参数,返回装饰器函数decorator;decorator接收被装饰的method,返回包装函数wrapper。
  • 异常匹配:使用isinstance(e, tuple(aware))判断异常实例e是否属于aware列表中的任意异常类,这是Python中捕获多异常的标准写法。
  • 兼容可变参数:wrapper中加入*args, **kwargs可以让装饰器适配带额外参数的方法,增强通用性。
  • 可选上下文保留:如果需要保留原异常的追踪信息,可以将raise response改为raise response from e,这样在报错时会显示原异常的触发原因。

使用验证:

# 测试用类
class Calculator:
    def __init__(self, left, right):
        self.left = left
        self.right = right

    @exception_adapter(aware=[OverflowError,], response=ValueError("Result is too big!"))
    def evaluate(self):
        return self.left ** self.right

# 触发异常
calc = Calculator(10**100, 10**100)
calc.evaluate()  # 会抛出 ValueError: Result is too big!

内容的提问来源于stack exchange,提问作者Miłosz Brzechczyn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 02:55:16