关于PyPI Schema模块Or()方法仅允许单一键的技术咨询
解决PyPI Schema模块Or()方法允许同时存在多个键的问题
我之前也踩过这个坑!PyPI的Schema模块里的Or()确实是设计成只要匹配任意一个选项就通过,不会限制其他选项同时存在。要实现你需要的“仅选其一、互斥键”的约束,得自己添加自定义校验逻辑——官方文档里确实没内置这个功能,我来给你两种可行的方案:
方案一:全局自定义验证器(推荐)
写一个全局验证函数,检查目标键的数量是否恰好为1,把它作为Schema的第二个参数传入,对整个字典做校验:
from schema import Schema, Or, SchemaError def only_one_of(target_keys): """自定义验证器:确保目标键中恰好有一个存在""" def validator(data): matched_count = sum(1 for key in target_keys if key in data) if matched_count != 1: raise SchemaError(f"必须且只能包含{target_keys}中的一个键,当前找到{matched_count}个") return data return validator # 定义你的Schema,添加全局验证器 test_schema = Schema( { Or("first", "schema"): str, "second": int }, only_one_of(["first", "schema"]) ) # 测试合法案例 valid_case1 = {"first": "test", "second": 15} test_schema.validate(valid_case1) # 正常返回结果 valid_case2 = {"schema": "check", "second": 15} test_schema.validate(valid_case2) # 正常返回结果 # 测试非法案例(同时存在两个键) invalid_case = {"first": "test", "schema": "check", "second": 15} test_schema.validate(invalid_case) # 抛出SchemaError异常
方案二:结合And()与键级验证
如果你想把校验逻辑绑定在键的规则上,也可以用And()包裹Or,同时添加一个检查键唯一性的逻辑:
from schema import Schema, Or, And, SchemaError test_schema = Schema({ And( Or("first", "schema"), lambda key, data: sum(1 for k in ["first", "schema"] if k in data) == 1 ): str, "second": int }) # 测试效果和方案一一致
不过这种方式的可读性不如全局验证器,尤其是当互斥键数量较多的时候,全局验证器更清晰。
简单总结一下:Or()的核心是“允许任一匹配”,而非“仅允许任一匹配”,所以互斥约束需要我们自己通过自定义验证器来实现,上面的两种方法都能满足你的需求~
内容的提问来源于stack exchange,提问作者chomes
相关产品推荐
相关产品推荐

