1

dict値が次のルールに従っているを検証したいと思います。

  • 値は、単一floatまたはList(float)
  • 単一floatの場合、値は 1 でなければなりません
  • の場合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)

ここで、もう 1 つの条件を実装する必要があります。

  • の場合、 のList(float)sum1 にfloat等しくなければなりません

したがって、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.
を検証するとdocument4fieldと にint=0なりvalue=0.5ます。したがって、エラーメッセージは理にかなっています。

リスト全体が関数に渡されないのはなぜですか? ここで何が欠けていますか?

4

2 に答える 2