目录
- 一、前置说明
- 1、总体目录
- 2、相关回顾
- 3、本节目标
- 二、操作步骤
- 1、项目目录
- 2、代码实现
- 3、测试代码
- 4、日志输出
- 三、后置说明
- 1、要点小结
- 2、下节准备
一、前置说明
1、总体目录
- 《 pyparamvalidate 参数校验器,从编码到发布全过程》
2、相关回顾
- 添加 常用校验方法,校验常见数据格式
3、本节目标
- 添加 自定义校验方法,让用户自定义校验规则
二、操作步骤
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
库,自定义复杂的校验方法
点击返回主目录