在 Cerberus 中对递归数据结构模式进行建模的正确方法是什么?
from cerberus import Validator, schema_registry
schema_registry.add("leaf", {"value": {"type": "integer", "required": True}})
schema_registry.add("tree", {"type": "dict", "anyof_schema": ["leaf", "tree"]})
v = Validator(schema = {"root":{"type": "dict", "schema": "tree"}})
错误:
cerberus.schema.SchemaError: {'root': [{
'schema': [
'no definitions validate', {
'anyof definition 0': [{
'anyof_schema': ['must be of dict type'],
'type': ['null value not allowed'],
}],
'anyof definition 1': [
'Rules set definition tree not found.'
],
},
]},
]}
上述错误表明需要为
tree
定义规则集:
from cerberus import Validator, schema_registry, rules_set_registry
schema_registry.add("leaf", {"value": {"type": "integer", "required": True}})
rules_set_registry.add("tree", {"type": "dict", "anyof_schema": ["leaf", "tree"]})
v = Validator(schema = {"root":{"type": "dict", "schema": "tree"}})
v.validate({"root": {"value": 1}})
v.errors
v.validate({"root": {"a":{"value": 1}}})
v.errors
v.validate({"root": {"a": {"b": {"c": {"value": 1}}}}})
v.errors
输出:
False
{'root': ['must be of dict type']}
对于所有 3 个示例。
理想情况下,我希望以下所有文件都能通过验证:
v = Validator(schema = {"root":{"type": "dict", "schema": "tree"}})
assert v.validate({"root": {"value": 1}}), v.errors
assert v.validate({"root": {"a":{"value": 1}}}), v.errors
assert v.validate({"root": {"a": {"b": {"c": {"value": 1}}}}}), v.errors
from cerberus import Validator
class RecursiveValidator(Validator):
def _validate_type_tree(self, value):
if not isinstance(value, dict):
return False
for v in value.values():
if isinstance(v, dict):
if 'value' in v:
if not isinstance(v['value'], int):
return False
else:
if not self._validate_type_tree(v):
return False
else:
return False
return True
schema = {'root': {'type': 'tree', 'required': True}}
v = RecursiveValidator(schema)
assert v.validate({'root': {'value': 1}}), v.errors
assert v.validate({'root': {'a': {'value': 1}}}), v.errors
assert v.validate({'root': {'a': {'b': {'c': {'value': 1}}}}}), v.errors