添加 自定义校验方法,让用户自定义校验规则

简介: 添加 自定义校验方法,让用户自定义校验规则

一、前置说明


1、本节目标

  • 添加 自定义校验方法,让用户自定义校验规则


2、相关回顾


二、操作步骤


1、项目目录


  • atme : @me 用于存放临时的代码片断或其它内容。
  • pyparamvalidate : 新建一个与项目名称同名的package,为了方便发布至 pypi
  • core : 用于存放核心代码。
  • tests : 用于存放测试代码。
  • utils : 用于存放一些工具类或方法。


2、代码实现

pyparamvalidate/core/validator.py

...
class Validator(metaclass=RaiseExceptionMeta):
    def __init__(self, value, field=None, rule_des=None):
        self.value = value
        self._field = field
        self._rule_des = rule_des
    def customize(self, validate_method, *args, exception_msg=None, **kwargs) -> Self:
        """
        注意事项:请参考示例 3
        示例 1:使用 lambda 函数
            '''
            Validator(4).customize(validate_method=lambda x: x % 2 == 0)
            '''
        示例 2:函数只有一个参数
            '''
            def even_number_validator(value):
                return value % 2 == 0
            Validator(4).customize(validate_method=even_number_validator)
            '''
        示例 3:如果函数有多个参数,必须将 "待校验参数" 放在第一位
            '''
            # 方法定义注意事项:如果有多个参数,必须将 "待校验参数" 放在第一位
            def even_number_validator(value, threshold):
                return value % 2 == 0 and value > threshold
            # 方法调用注意事项:第一个参数不要传值,exception_msg 必须以关键字参数传值。
            Validator(12).customize(even_number_validator, 10, exception_msg='value must be an even number and greater than 10.')
            '''
        """
        try:
            return validate_method(self.value, *args, **kwargs)
        except TypeError as e:
            raise CallValidateMethodError(
                f'''
                Note:
                1. Please do not send value to first argument in calling {validate_method.__name__}.
                2. You must pass the value for "exception_msg" as a "keyword argument".
                3. please refer to: 
                    def even_number_validator(value, threshold):
                        return value % 2 == 0 and value > threshold
                    Validator(12).customize(even_number_validator, 10, exception_msg='value must be an even number and greater than 10.')
                4. origin error: {e}'
                ''')
    ...


3、测试代码

pyparamvalidate/tests/test_validator.py

def test_customize_validator_01():
    Validator(4).customize(validate_method=lambda x: x % 2 == 0)
    with pytest.raises(ValueError) as exc_info:
        Validator(3).customize(validate_method=lambda x: x % 2 == 0, exception_msg='value must be an even number.')
    assert "value must be an even number." in str(exc_info.value)
def test_customize_validator_02():
    def even_number_validator(value):
        return value % 2 == 0
    Validator(4).customize(validate_method=even_number_validator)
    with pytest.raises(ValueError) as exc_info:
        Validator(3).customize(validate_method=lambda x: x % 2 == 0, exception_msg='value must be an even number.')
    assert "value must be an even number." in str(exc_info.value)
def test_customize_validator_03():
    def even_number_validator(value, threshold):
        return value % 2 == 0 and value > threshold
    Validator(12).customize(even_number_validator, 10)
    Validator(12).customize(even_number_validator, 10,
                            exception_msg='value must be an even number and greater than 10.')
    Validator(12).customize(even_number_validator, threshold=10,
                            exception_msg='value must be an even number and greater than 10.')
    with pytest.raises(ValueError) as exc_info:
        Validator(2).customize(validate_method=even_number_validator, threshold=10,
                               exception_msg='value must be an even number and greater than 10.')
    assert "value must be an even number and greater than 10." in str(exc_info.value)
    with pytest.raises(CallValidateMethodError) as exc_info:
        Validator(2).customize(even_number_validator, 2, 10,
                               exception_msg='value must be an even number and greater than 10.')
...


4、日志输出

执行 test 的日志如下,验证通过:

test_validator.py::test_customize_validator_01 PASSED                    [  3%]
test_validator.py::test_customize_validator_02 PASSED                    [  7%]
test_validator.py::test_customize_validator_03 PASSED                    [ 11%]


三、后置说明


1、要点小结

  • 自定义校验方法的定义和调用注意事项,见 customize 方法中的示例说明。
  • customize 方法,复制粘贴至 ParameterValidator 类中并对方法注释进行适当修改,方便 Pycharm 智能提示。
...
def customize(self, validate_method, *args, exception_msg=None, **kwargs) -> Self:
    """
    注意事项:请参考示例 3
    示例 1:使用 lambda 函数
        '''
        @ParameterValidator("param").customize(lambda x: x % 2 == 0, exception_msg="Value must be an even number")
        def example_function(param):
            return param
        '''
    示例 2:函数只有一个参数
        '''
        def even_number_validator(value):
            return value % 2 == 0
        @ParameterValidator("param").customize(even_number_validator, exception_msg="Value must be an even number")
        def example_function(param):
            return param
        '''
    示例 3:如果函数有多个参数,必须将 "待校验参数" 放在第一位
        '''
        # 方法定义注意事项:如果有多个参数,必须将 "待校验参数" 放在第一位
        def even_number_validator(value, threshold):
            return value % 2 == 0 and value > threshold
        # 方法调用注意事项:第一个参数不要传值,exception_msg 必须以关键字参数传值。
        @ParameterValidator("param").customize(even_number_validator, 10, exception_msg="Value must be an even number")
        def example_function(param):
            return param
        '''
    """
    ...
    ...


2、下节准备

  • 使用 schema 库,自定义复杂的校验方法

点击进入《Python装饰器从入门到进阶》总目录

目录
相关文章
|
6月前
|
Java Spring 容器
详解java参数校验之:顺序校验、自定义校验、分组校验(@Validated @GroupSequence)
详解java参数校验之:顺序校验、自定义校验、分组校验(@Validated @GroupSequence)
|
7月前
ElementUi配置自定义校验规则-校验IP和IP段
ElementUi配置自定义校验规则-校验IP和IP段
319 1
|
7月前
|
SQL 测试技术 数据安全/隐私保护
密码组件校验规则该如何测试?
密码组件校验规则该如何测试?
105 0
|
7月前
|
数据格式 Python
添加 常用校验方法,校验常见数据格式
添加 常用校验方法,校验常见数据格式
72 0
分组校验和自定义校验
分组校验和自定义校验
97 0
|
JSON 搜索推荐 Java
自定义规则异常返回|学习笔记
快速学习自定义规则异常返回
自定义规则异常返回|学习笔记