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

Python中如何用装饰器处理AssertionError替代嵌套try/except块

实现方案

你遇到的NameError是因为装饰器在函数定义阶段就会执行,此时函数的参数x、y还未被初始化,自然无法识别。我们可以通过带参数的装饰器工厂实现你要的效果,完全替代嵌套的try/except块,以下是可直接运行的完整代码:

完整实现代码

# 断言异常捕获装饰器:捕获校验函数抛出的AssertionError,打印错误并返回校验结果
def catch_assert(func):
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except AssertionError as exc:
            print(exc)
            return False
    return wrapper

# 自定义校验规则,用catch_assert装饰自动处理异常
@catch_assert
def is_int(x):
    assert isinstance(x, int), f"'{x}' is not an integer"
    return True

@catch_assert
def is_str(y):
    assert isinstance(y, str), f"'{y}' is not a string"
    return True

# 校验装饰器工厂:传入要校验的参数名、对应的校验函数,返回实际装饰器
def validate(param_name: str, check_func):
    def decorator(func):
        def wrapper(*args, **kwargs):
            # 自动映射参数名和传入的参数值,兼容位置参数、关键字参数
            import inspect
            func_sig = inspect.signature(func)
            bound_args = func_sig.bind(*args, **kwargs)
            bound_args.apply_defaults()
            target_value = bound_args.arguments[param_name]
            # 校验失败直接终止执行,校验通过才运行后续逻辑
            if not check_func(target_value):
                return
            return func(*args, **kwargs)
        return wrapper
    return decorator

# 装饰目标函数,装饰器从下到上执行,先校验y再校验x
@validate("x", is_int)
@validate("y", is_str)
def pretty_function(x: int, y: str):
    print(f'There is/are {x} {y}')

测试运行

pretty_function(2,'cat')
pretty_function(2,3)
pretty_function('2','cat')

输出结果

There is/are 2 cat
'3' is not a string
'2' is not an integer

逻辑说明

  1. 你之前写的test_assertion存在逻辑冗余:else分支重复执行了一次被装饰函数,优化后仅执行一次,校验成功返回结果、失败返回False
  2. validate作为装饰器工厂,在函数定义阶段仅接收配置(参数名、校验规则),实际校验逻辑推迟到函数调用时执行,避免了参数未定义的报错
  3. 新增校验规则仅需要编写对应加了@catch_assert的校验函数,再给目标函数加一层@validate(参数名, 新校验函数)即可,无需嵌套异常处理块,可读性极强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 18:54:05