带有附加参数的python-attrs中的自定义验证器

我使用attrs定义了几个这样的类:


from attr import attrs, attrib, validators


@attrs

class MyClass:

    name = attrib(])

    @name.validator

    def check_length(self, attribute, value):

        if not (3 <= len(value) <= 30):

            raise ValueError("Name must be between 3 and 30 characters")


    description = attrib()

    @description.validator

    def check_length(self, attribute, value):

        if not (10 <= len(value) <= 400):

            raise ValueError("Description must be between 10 and 400 characters")

对于几个属性,我需要创建一个验证器来检查数据是否在某个范围内。我想避免重复,因此我可以创建一个自定义验证器,在其中为min和max传递一些额外的参数,如下所示:


def range_validator(instance, attribute, value, min_value, max_value):

    if  min_value >= len(value) >= max_value:

        raise ValueError("Must be between {} and {}".format(min_value, max_value))

但是然后我不知道如何通过传递额外的参数(min_value和max_value)从attrib()内部调用此验证器,我的意思是执行以下操作:


name = attrib(validator=[range_validator(self, 10, 30)])


米脂
浏览 157回答 1
1回答

德玛西亚99

你可以使用functools.partial:def range_validator(instance, attribute, value, min_value, max_value):&nbsp; &nbsp; lv = len(value)&nbsp; &nbsp; if min_value > lv or lv > max_value:&nbsp; &nbsp; &nbsp; &nbsp; raise ValueError("Must be between {} and {}".format(min_value, max_value))@attrsclass C:&nbsp; &nbsp; x = attrib(validator=partial(range_validator, min_value=10, max_value=30))另外,您可以使用闭包:def make_range_validator(min_value, max_value):&nbsp; &nbsp; def range_validator(instance, attribute, value):&nbsp; &nbsp; &nbsp; &nbsp; lv = len(value)&nbsp; &nbsp; &nbsp; &nbsp; if min_value > lv or lv > max_value:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; raise ValueError("Must be between {} and {}".format(min_value, max_value))&nbsp; &nbsp; return range_validator@attrsclass C:&nbsp; &nbsp; x = attrib(validator=make_range_validator(10, 30))我个人更喜欢闭包工厂方法,因为它们更明确地说明你在做什么。局部对象总是对我有些特别,但这可能就是我。(请注意,我冒昧地修复了您验证器中的逻辑错误——您可能也想应用它。:))
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python