Python函数参数如何正确且便捷地进行验证?
Python函数参数验证的便捷实现方案
一、原生无依赖方案:通用装饰器批量检查
如果你不想引入第三方库,可以自己实现一个可复用的装饰器,借助inspect模块自动获取函数参数列表,在函数执行前统一完成验证:
import inspect def require_non_empty_args(func): sig = inspect.signature(func) param_names = list(sig.parameters.keys()) def wrapper(*args, **kwargs): # 合并位置参数与关键字参数为字典 arg_map = dict(zip(param_names, args)) arg_map.update(kwargs) # 筛选出为空的参数 empty_params = [name for name in param_names if not arg_map.get(name)] if empty_params: raise ValueError(f"参数 {', '.join(empty_params)} 不能为空或None") return func(*args, **kwargs) return wrapper # 直接给函数加装饰器即可 @require_non_empty_args def test_function(user_id, name, response, model): # 函数业务逻辑 print("参数验证通过")
注意:not x的判断会把空字符串、0、空列表等也判定为“空”,如果仅需排除None,可将判断条件改为arg_map.get(name) is None。
二、专业验证方案:用Pydantic实现强校验
如果需要更全面的验证能力(比如类型检查、格式约束等),推荐使用pydantic库,它是Python生态中常用的数据验证工具,能自动完成参数前置校验:
先安装依赖:
pip install pydantic
方式1:基于模型定义参数
from pydantic import BaseModel, ValidationError class TestParams(BaseModel): user_id: str # 未设默认值则为必填项,同时支持类型校验 name: str response: str model: str def test_function(params: TestParams): # 函数业务逻辑 print(f"参数验证通过,user_id: {params.user_id}") # 调用示例 try: test_function(TestParams(user_id="123", name="Alice", response="ok", model="gpt-3")) except ValidationError as e: print(e)
当参数缺失、为None或类型不匹配时,Pydantic会自动抛出包含详细信息的验证错误,无需手动编写检查逻辑。
方式2:用装饰器直接校验函数参数
from pydantic import validate_arguments, ValidationError @validate_arguments def test_function(user_id: str, name: str, response: str, model: str): # 函数业务逻辑 print("参数验证通过") # 调用示例 try: test_function(user_id="123", name="", response="ok", model="gpt-3") # 空字符串会触发str类型校验 except ValidationError as e: print(e)
这种方式和原生函数调用逻辑完全一致,无需额外定义模型,非常便捷。如果需要允许特定空值,可以在类型注解中添加Optional并配置约束。
三、极简原生方案:特殊默认值+断言
针对简单场景,也可以用特殊默认值标记必填项,再批量检查:
# 定义唯一的特殊值,用于判断参数是否被传入 _REQUIRED = object() def test_function(user_id=_REQUIRED, name=_REQUIRED, response=_REQUIRED, model=_REQUIRED): for param_name, param_value in locals().items(): if param_value is _REQUIRED: raise ValueError(f"参数 {param_name} 为必填项") if not param_value: raise ValueError(f"参数 {param_name} 不能为空或None") # 函数业务逻辑 print("参数验证通过")
这种方式无需依赖任何模块,适合单个简单函数的快速验证,但复用性不如装饰器方案。
内容的提问来源于stack exchange,提问作者Clyde
相关产品推荐
相关产品推荐

