我有一个这样的Python输入字典模式,
SCHEMA = {
'mode': ('mode_1', 'mode_2', 'mode_3'),
'method': ('method_1', 'method_2'),
'other': {
'x1': [1, 365],
'x2': [0., 1.0]
}
}
我要验证给定的输入字典,
inp = {
'mode': 'mode_1',
'method': 'method_1',
'other': {
'x1': 1,
'x2': 1.0
}
}
('mode_1', 'mode_2', 'mode_3')
。对于所有键值对来说,都是明智的选择。 我可以考虑使用循环来实现。但是无法想到一种通用的方法。如果我只是遍历两个字典并比较它们的值,那么如果架构发生更改,就必须重写逻辑。
是否有任何直接的方法来验证模式?
答案 0 :(得分:3)
您可以尝试使用此递归功能:
def validate(input_, db):
for k,v in input_.items():
if isinstance(v, dict):
return validate(v, db.get(k))
else:
if v not in db.get(k):
return False
return True
然后您将其命名为:
In [21]: validate(inp, SCHEMA)
Out[21]: True
如果将inp更改为:
In [16]: inp = {
...: 'mode': 'mode_2',
...: 'method': 'method_2',
...: 'other': {
...: 'x1': 4, # This is not valid
...: 'x2': 1.0
...: }
...:
...: }
In [17]: validate(inp, SCHEMA)
Out[17]: False
或
In [20]: inp = {
...: 'mode': 'mode_2',
...: 'method': 'method_2',
...: 'other': {
...: 'x1': 1,
...: 'x2': 1.0
...: }
...:
...: }
In [21]: validate(inp, SCHEMA)
Out[21]: True
答案 1 :(得分:2)
字典就像json,因此您可以使用jsonschema:
import json
from jsonschema import validate
# A sample schema, YOU WILL HAVE TO DESIGN ONE .
schema = {
"type" : "object",
"properties" : {
"price" : {"type" : "number"},
"name" : {"type" : "string"},
},
}
测试
# If no exception is raised by validate(), the instance is valid.
validate(instance={"name" : "Eggs", "price" : 34.99}, schema=schema)
validate(instance={"name" : "Eggs", "price" : "Invalid"}, schema=schema)
#error
Traceback (most recent call last):
ValidationError: 'Invalid' is not of type 'number'
有关更多详细信息,请检查documentation。
要获取适用于您架构的有效Json Schema,可以使用this。
只需替换' with " and () with []
。
答案 2 :(得分:-1)
您可以使用递归:
SCHEMA = {'mode': ('mode_1', 'mode_2', 'mode_3'), 'method': ('method_1', 'method_2'), 'other': {'x1': [1, 365], 'x2': [0.0, 1.0]}}
inp = {'mode': 'mode_1', 'method': 'method_1', 'other': {'x1': 1, 'x2': 1.0}}
def check(d, s):
return all(b in s[a] if not isinstance(b, dict) else check(b, s[a]) for a, b in d.items())
print(check(inp, SCHEMA))
输出:
True
编辑:以上解决方案仅检查有效密钥的迭代中是否存在单个密钥。但是,要处理更具体的检查(例如您的第四个条件),可以为不同的类型构建处理程序:
t = {'tuple':lambda x, y:x in y, 'list':lambda x, y:x > y[0] and x < y[-1]}
def check(d, s):
return all(check(b, s[a]) if isinstance(b, dict) else t[type(s[a]).__name__](b, s[a]) for a, b in d.items())