首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cerberus元组模式验证器

cerberus元组模式验证器
EN

Stack Overflow用户
提问于 2018-08-21 11:41:26
回答 2查看 952关注 0票数 0

我有一个变量声明,如下

代码语言:javascript
复制
my_var = typing.List[typing.Tuple[int, int]]

并且我想编写一个验证器,如下所示

代码语言:javascript
复制
schema_validator = "my_var": {
    "type": "list",
    "empty": False,
    "items": [
        {"type": "tuple"},
        {"items": [
            {"type": "int"}, {"type": "int"}
        ]}
    ]
}

在Cerberus文档中,它没有为tuples指定验证器示例。

如何做到这一点呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-27 03:31:10

给定您的typevar typing.List[typing.Tuple[int, int]],您会得到一个任意长度的双值元组列表,其中每个值都是一个整数。

代码语言:javascript
复制
class MyValidator(Validator):
    # add a type definition to a validator subclass
    types_mapping = Validator.types_mapping.copy()
    types_mapping['tuple'] = TypeDefinition((tuple,), ())


schema = {
    'type': 'list',
    'empty': False,
    'schema': {  # the number of items is undefined
        'type': 'tuple',
        'items': 2 * ({'type': 'int'},)
    }
}

validator = MyValidator(schema)

理解itemsschema规则的区别很重要。

请记住,默认的list类型实际上映射到更抽象的Sequence type,您可能希望为此添加另一个更严格的类型。

票数 1
EN

Stack Overflow用户

发布于 2018-08-26 01:52:30

虽然这不是最干净的解决方案,但它肯定会做你想要的。

代码语言:javascript
复制
from cerberus import Validator, TypeDefinition

class MyValidator(Validator):
    def __init__(self, *args, **kwargs):
        # Add the tuple type
        tuple_type = TypeDefinition("tuple", (tuple,), ())
        Validator.types_mapping["tuple"] = tuple_type
        # Call the Validator constructor
        super(MyValidator, self).__init__(*args, **kwargs)

    def _validate_is_int_two_tuple(self, is_int_two_tuple, field, value):
        ''' Test that the value is a 2-tuple of ints

        The rule's arguments are validated against this schema:
        {'type': 'boolean'}
        '''
        if is_int_two_tuple:
            # Check the type
            if type(value) != tuple:
                self._error(field, "Must be of type 'tuple'")
            # Check the length
            if len(value) != 2:
                self._error(field, "Tuple must have two elements")
            # Check the element types
            if type(value[0]) != int or type(value[1]) != int:
                self._error(field, "Both tuple values must be of type 'int'")

data = {"mylist": [(1,1), (2,2), (3,3)]}

schema = {
    "mylist": {
        "type": "list",
        "schema": {
            "type": "tuple",
            "is_int_two_tuple": True
        }
    }
}

v = MyValidator(schema)
print("Validated: {}".format(v.validate(data)))
print("Validation errors: {}".format(v.errors))
print("Normalized result: {}".format(v.normalized(data)))

因此,正如bro-grammer所指出的,自定义数据类型将为您提供类型验证,但仅此而已。从您提供的模式来看,您似乎还想验证其他特性,比如元组的长度和元组中元素的类型。要做到这一点,需要的不仅仅是元组的简单TypeDefinition

将Validator扩展为包含此特定用例的规则并不理想,但它可以做您想要的事情。更全面的解决方案是创建一个TupleValidator子类,它具有验证元组的长度、元素类型、顺序等规则。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51941251

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档