元组的 cerberus 模式验证器
cerberus schema validator for tuples
我有一个变量声明如下
my_var = typing.List[typing.Tuple[int, int]]
我想写一个验证器如下
schema_validator = "my_var": {
"type": "list",
"empty": False,
"items": [
{"type": "tuple"},
{"items": [
{"type": "int"}, {"type": "int"}
]}
]
}
在 Cerberus 文档中,它没有为 tuples
指定验证器示例。
如何实现?
虽然这不是最干净的解决方案,但它肯定会满足您的需求。
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
。
扩展验证器以包含针对此特定用例的规则并不理想,但它会满足您的要求。更全面的解决方案是创建一个 TupleValidator
子类,该子类具有验证元组长度、元素类型、顺序等的规则。
给定您的 typevar typing.List[typing.Tuple[int, int]]
,您期望一个任意长度的双值元组列表,其中每个值都是一个整数。
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)
了解 items and the schema 规则的区别很重要。
请注意,默认 list
类型实际上映射到更抽象的 Sequence
type,您可能想为此添加另一个更严格的类型。
我有一个变量声明如下
my_var = typing.List[typing.Tuple[int, int]]
我想写一个验证器如下
schema_validator = "my_var": {
"type": "list",
"empty": False,
"items": [
{"type": "tuple"},
{"items": [
{"type": "int"}, {"type": "int"}
]}
]
}
在 Cerberus 文档中,它没有为 tuples
指定验证器示例。
如何实现?
虽然这不是最干净的解决方案,但它肯定会满足您的需求。
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
。
扩展验证器以包含针对此特定用例的规则并不理想,但它会满足您的要求。更全面的解决方案是创建一个 TupleValidator
子类,该子类具有验证元组长度、元素类型、顺序等的规则。
给定您的 typevar typing.List[typing.Tuple[int, int]]
,您期望一个任意长度的双值元组列表,其中每个值都是一个整数。
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)
了解 items and the schema 规则的区别很重要。
请注意,默认 list
类型实际上映射到更抽象的 Sequence
type,您可能想为此添加另一个更严格的类型。