寻求类似attrs的Python函数可选轻量参数验证库
推荐用Param库
Param是完全贴合你需求的轻量参数验证工具:
- 支持给普通函数的参数加声明式验证,风格和attrs一模一样
- 验证是可选的:只有你显式加了验证规则的参数才会做运行时检查,没加规则的参数只靠类型提示做静态校验(比如mypy),不会强制做不必要的类型检查,对Callable、numpy数组这类复杂类型友好
- 内置了常用的验证逻辑(比如范围、非空),也能轻松写自定义验证器
用Param重写你的示例函数
import param @param.parameterized def foo( a: int = param.Integer(gt=0), # 确保a是正整数 b: float = param.Number(gt=0, le=1), # 确保b在(0,1]区间 c: str = param.String(allow_blank=False) # 确保c非空 ) -> None: # 直接使用验证后的参数即可 pass
如果需要自定义验证逻辑,比如更复杂的规则,也可以直接传验证函数:
def custom_a_validator(value): if not isinstance(value, int) or value <= 0: raise ValueError(f"'a'必须是正整数,实际得到: {value}") return value @param.parameterized def foo( a: int = param.Parameter(validate=custom_a_validator), b: float = param.Number(gt=0, le=1), c: str = param.String(allow_blank=False) ) -> None: pass
备选:自己写轻量装饰器
如果不想额外装库,也可以用装饰器实现只验证指定参数的逻辑,完全可控:
import inspect from functools import wraps # 定义验证器装饰器,只针对指定参数做检查 def validate_param(param_name, validator): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): sig = inspect.signature(func) bound_args = sig.bind(*args, **kwargs).arguments if param_name in bound_args: validator(bound_args[param_name]) return func(*args, **kwargs) return wrapper return decorator # 定义具体的验证逻辑 def check_positive_int(val): if not isinstance(val, int) or val <= 0: raise ValueError(f"'a'必须是正整数,实际得到: {val}") def check_b_range(val): if not (0 < val <= 1): raise ValueError(f"'b'必须在(0,1]区间,实际得到: {val}") def check_non_empty_str(val): if not isinstance(val, str) or not val.strip(): raise ValueError(f"'c'不能为空,实际得到: {val!r}") # 给函数参数加验证 @validate_param("a", check_positive_int) @validate_param("b", check_b_range) @validate_param("c", check_non_empty_str) def foo(a: int, b: float, c: str) -> None: # 业务逻辑 pass
这种方式没有任何额外依赖,完全按照你的需求只验证需要的参数,不会对其他参数做多余检查。
内容的提问来源于stack exchange,提问作者Shai Avr
相关产品推荐
相关产品推荐

