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

如何在装饰器中比较多参数?编写JSON验证装饰器遇问题求助

JSON验证装饰器实现指南

首先得说下你现有代码里的几个小问题,这样我们能更好地修正方向:

  • 装饰器结构不对:带参数的装饰器得先返回装饰器函数,你现在直接在里面调用f(),会导致被装饰的函数在装饰阶段就执行了,而不是等你调用它的时候才执行,完全不符合装饰器的使用逻辑。
  • 判断逻辑不靠谱:把JSON转成字符串然后检查包含关系很容易出错,比如如果键名有重叠(比如允许"name",但JSON里有"username"),就会误判。正确的做法应该是直接对比JSON的键集合。
  • 异常抛出方式不对:你直接return ValueError(...),这不会抛出异常,只是返回了一个异常对象而已,得用raise语句才行。

接下来给你一个完整的可运行实现,同时解决“支持更多参数”的问题:

# 定义带可变参数的装饰器,*allowed_keys接收所有允许的键
def mydecorator(*allowed_keys):
    def decorator(func):
        def wrapper(*args, **kwargs):
            # 先调用被装饰的函数,拿到要验证的JSON数据
            sent_json = func(*args, **kwargs)
            # 把JSON的键和允许的键都转成集合,方便对比
            json_keys = set(sent_json.keys())
            allowed_set = set(allowed_keys)
            # 找出JSON中存在但不在允许列表里的键
            extra_keys = json_keys - allowed_set
            if extra_keys:
                raise ValueError(f"JSON包含不允许的键: {', '.join(extra_keys)}")
            # 验证通过,返回原函数的结果
            return sent_json
        return wrapper
    return decorator

# 测试场景1:符合要求的JSON
@mydecorator("first_name", "last_name")
def get_valid_json():
    return {"first_name": "James", "last_name": "Bond"}

# 测试场景2:包含额外键的JSON
@mydecorator("first_name")
def get_invalid_json():
    return {"first_name": "James", "last_name": "Bond", "age": 30}

# 验证正确情况
print(get_valid_json())  # 输出: {'first_name': 'James', 'last_name': 'Bond'}

# 验证错误情况,会抛出异常
try:
    get_invalid_json()
except ValueError as e:
    print(e)  # 输出: JSON包含不允许的键: last_name, age

关于“如何支持更多参数”的问题

其实上面的实现已经完美解决了这个需求:
我们用*allowed_keys这个可变参数语法,让装饰器可以接收任意数量的允许键。比如你要检查5个键,直接写@mydecorator("key1", "key2", "key3", "key4", "key5")就行,装饰器会自动把所有传入的参数收集成一个元组,转成集合后和JSON的键做对比,不管参数多少都能轻松处理。

另外补充一点:如果你的JSON是作为函数参数传入的(而不是函数返回的),只需要修改wrapper里的逻辑,去检查传入的参数即可,比如:

def wrapper(json_data, *args, **kwargs):
    # 直接检查传入的json_data
    json_keys = set(json_data.keys())
    # 后续逻辑和之前一样...

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:49:45