我想验证 a dict
,其中的值符合以下规则:
- 值必须是单个
float
或List(float)
- 如果是 single
float
,则值必须为 1 - 如果是 a
List(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)
现在,我必须再实现一个条件:
- 如果是 a
List(float)
,则sum
offloat
必须等于 1
因此,我编写了文档( https://docs.python-cerberus.org/en/stable/validation-rules.html) check_with
中描述的函数。
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
现在,只要值是 a List(float)
,只有第一个元素list
会被注入我的函数,导致 a TypeError: 'float' object is not iterable
。
验证时document4
,field
将是int=0
和value=0.5
。所以错误信息是有道理的。
我想知道,为什么整个列表没有传递给我的函数?我在这里想念什么?