我想验证一个dict
,其中的值遵循以下规则:
float
或List(float)
float
,则该值必须为1List(float)
,则每个浮点必须为正以下是我的代码和一些正常工作的测试断言:
import cerberus
v = cerberus.Validator()
schema1 = {
"key1": {
"type": ["float", "list"],
"min": 1,
"max": 1,
"schema": {"type": "float", "min": 0},
}
}
document1 = {"key1": 1}
document2 = {"key1": 5}
document3 = {"key1": "5"}
document4 = {"key1": [0.5, 0.3]}
document5 = {"key1": ["0.5", 0.3]}
assert v.validate(document1, schema1)
assert not v.validate(document2, schema1)
assert not v.validate(document3, schema1)
assert v.validate(document4, schema1)
assert not v.validate(document5, schema1)
现在,我必须执行另一个条件:
List(float)
,则float
的sum
必须等于1因此,我编写了一个check_with
函数,如文档(https://docs.python-cerberus.org/en/stable/validation-rules.html)中所述
from cerberus import Validator
class MyValidator(Validator):
def _check_with_sum_eq_one(self, field, value):
"""Checks if sum equals 1"""
if sum(value) != 1:
self._error(field, f"Sum of '{field}' must exactly equal 1")
调整后的架构和测试文档如下所示:
v = MyValidator()
schema2 = {
"key1": {
"type": ["float", "list"],
"min": 1,
"max": 1,
"schema": {"type": "float", "min": 0, "max": 1, "check_with": "sum_eq_one"},
}
}
document1 = {"key1": 1}
document2 = {"key1": 5}
document3 = {"key1": "5"}
document4 = {"key1": [0.5, 0.3]} # error
document5 = {"key1": ["0.5", 0.3]} # error
document6 = {"key1": [0.5, 0.5]} # error
现在,每当值是List(float)
时,只有list
的第一个元素将被注入到我的函数中,从而产生一个TypeError: 'float' object is not iterable
。
验证document4
时field
将是int=0
和value=0.5
。因此,错误消息是有意义的
我想知道,为什么整个列表没有传递给我的函数?我错过了什么
如果您试图捕获错误并仅在错误发生时继续执行您的函数,该怎么办?例如,以这种方式:
下面的答案工作正常。然而,在我看来,这太复杂了
首先,调整
schema2
如下:接下来,调整
_check_with_sum_eq_one
,如下所示:最后,断言一切都按预期进行
我不喜欢这里的事实是,如果所有列表成员都是
float
(if all([isinstance(x, float) for x in value])
)类型,我需要“手动”检查。在我看来,这个测试属于schema2
。然而,在某种程度上,我没有成功地调整schema2
,即float
类型的测试先于check_with
验证任何进一步简化此任务的提示将不胜感激
相关问题 更多 >
编程相关推荐