为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

米脂 2021-05-30 20:01:41
我使用attrs定义了几个这样的类:from attr import attrs, attrib, validators@attrsclass 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)])
查看完整描述

1 回答

?
德玛西亚99

TA贡献1770条经验 获得超3个赞

你可以使用functools.partial:


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

    lv = len(value)

    if min_value > lv or lv > max_value:

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


@attrs

class C:

    x = attrib(validator=partial(range_validator, min_value=10, max_value=30))

另外,您可以使用闭包:


def make_range_validator(min_value, max_value):

    def range_validator(instance, attribute, value):

        lv = len(value)

        if min_value > lv or lv > max_value:

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


    return range_validator


@attrs

class C:

    x = attrib(validator=make_range_validator(10, 30))

我个人更喜欢闭包工厂方法,因为它们更明确地说明你在做什么。局部对象总是对我有些特别,但这可能就是我。


(请注意,我冒昧地修复了您验证器中的逻辑错误——您可能也想应用它。:))


查看完整回答
反对 回复 2021-06-01
  • 1 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号