Voluptuous校验含2个指定结构字典的列表报MultipleInvalid错误如何解决
报错原因
当前Schema写法不符合Voluptuous的默认规则逻辑:
- 给
Schema传入列表作为校验规则时,Voluptuous默认要求:待校验列表的每一个元素必须同时满足列表内定义的所有校验规则,而非匹配任意一个规则即可。 - 现有写法等价于要求列表里每个字典的
field1同时等于'value1'和'value3',逻辑无法成立,因此触发校验报错。 - 补充规则说明:如果需要按列表位置严格匹配定长序列,要用元组而非列表包裹按顺序定义的规则。
正确配置方案
先导入需要的依赖组件:
from voluptuous import Schema, Required, All, Length, Any
根据实际校验需求选择对应写法即可:
按位置严格匹配
要求列表长度固定为2,第1个元素必须是field1='value1'的结构,第2个元素必须是field1='value3'的结构,顺序不可调换。
直接用元组包裹按顺序排列的规则:
test_data = [{'field1': 'value1', 'field2': 1}, {'field1': 'value3', 'field2': 2}] schema = Schema(( {Required('field1'): 'value1', Required('field2'): int}, {Required('field1'): 'value3', Required('field2'): int} )) assert schema(test_data) # 校验通过
不限制顺序,元素匹配任意合法结构即可
要求列表长度固定为2,每个元素只要符合两种字典结构的任意一种就通过校验(允许两个元素为同一种结构)。
用Any包裹可选规则,配合Length限制列表长度:
# 顺序调换也可以正常通过校验 test_data = [{'field1': 'value3', 'field2': 2}, {'field1': 'value1', 'field2': 1}] schema = Schema(All( [Any( {Required('field1'): 'value1', Required('field2'): int}, {Required('field1'): 'value3', Required('field2'): int} )], Length(2) )) assert schema(test_data) # 校验通过
不限制顺序,必须包含两种结构各一个
要求列表长度为2,两个字典分别对应两种不同结构,不允许出现两个元素为同一种结构的情况,顺序可任意调换。
增加自定义校验函数做精确匹配检查:
def check_exact_structure(data): field1_values = {item['field1'] for item in data} if field1_values != {'value1', 'value3'}: raise ValueError('列表必须同时包含field1为value1、value3的两个字典') return data schema = Schema(All( [Any( {Required('field1'): 'value1', Required('field2'): int}, {Required('field1'): 'value3', Required('field2'): int} )], Length(2), check_exact_structure )) # 合法用例:两种结构各一个,顺序任意 valid_data = [{'field1': 'value3', 'field2': 2}, {'field1': 'value1', 'field2': 1}] assert schema(valid_data) # 非法用例:两个元素为同一种结构,校验时会抛出错误 invalid_data = [{'field1': 'value1', 'field2': 1}, {'field1': 'value1', 'field2': 3}]
内容的提问来源于stack exchange,提问作者user10827150
相关产品推荐
相关产品推荐

