使用 Python Cerberus (v1.3.5) 验证递归数据结构(例如树)

问题描述 投票:0回答:1

在 Cerberus 中对递归数据结构模式进行建模的正确方法是什么?

尝试#1:

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.'
            ],
        },
    ]},
]}

尝试#2:

上述错误表明需要为

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
python recursion tree cerberus
1个回答
0
投票
据我所知,Cerberus 不支持递归模式。您应该使用自定义验证器:

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
    
© www.soinside.com 2019 - 2024. All rights reserved.