首页 > 解决方案 > 如何在 Python Clint 模块中创建自定义验证器

问题描述

我正在使用名为的 Python 包Clint来美化我的应用程序中所需的输入。在包中,您可以访问模块validators并将其结合使用prompt以正确要求用户输入数据。

由于模块中的内置验证器类列表相对较短,我一直在寻找在 Clint 中实现自定义验证器的可能性:

[FileValidator, IntegerValidator, OptionValidator, PathValidator, RegexValidator, ValidationError]

所以我写了下面的代码:

from clint.textui import prompt, validators

class NumberValidator(object):
    message = 'Input is not valid.'

    def __init__(self, message=None):
        if message is not None:
            self.message = message

    def __call__(self, value):
        """
        Validates the input.
        """
        try:
            if int(value) > 10:
                return value
            else:
                raise ValueError() 
        except (TypeError, ValueError):
            raise validators.ValidationError(self.message)

answer = prompt.query(f'Insert range in days:',
                      '365',
                      validators=[NumberValidator("Must to be > 10")],
                      batch=False)
print(answer)

它有效,但我发现解决方案有点混乱。那是因为使用这个解决方案,每次我需要执行新的不同类型的验证时,我都必须创建一个新类。

我认为,如果类可以以某种方式动态使用decorators,每次启动时都接受一个新函数,那会更好。但我发现自己在装饰师的主题上真的很糟糕。

所以我请你帮我为这个问题做一个更 Pythonic 的解决方案。

标签: pythonpython-3.xvalidationcommand-line-interfaceclint

解决方案


不确定这是否是最好的方法,但我可能会找到更好的方法来解决这个问题。在下面的代码中,我可以根据需要创建任意数量的自定义函数(custom_validation_1, custom_validation_2, ...) ,custom_validation_3然后只需更改validatorsprompt.query

from clint.textui import prompt, validators


class InputValidator(object):
    message = 'Input is not valid.'

    def __init__(self, fun, message=None, *args):
        if message is not None:
            self.message = message
        self.my_function = fun
        self.my_args = args

    def __call__(self, value):
        """
        Validates the input.
        """
        try:
            return self.my_function(value, *self.my_args)
        except (TypeError, ValueError):
            raise validators.ValidationError(self.message)


def custom_validation_1(value, number):
    if int(value) > int(number):
        return value
    else:
        raise ValueError


answer = prompt.query(f'Insert range in days:',
                      '365',
                      validators=[InputValidator(custom_validation_1,
                                                 "Must to be greater than 10",
                                                 10)],
                      batch=False)
print(answer)

推荐阅读