如何让Pydantic即时校验输入,验证合法范围后再进入下一字段
终端交互下的Pydantic输入验证优化
问题需求
需要在终端交互场景中实现:用户必须先输入合法的数字范围(仅含数字和逗号,可带空格),验证通过后才能进入姓名字段的输入;若数字范围输入不合法,持续提示重新输入,直到符合要求。
原代码问题
当前代码直接将两个input()作为参数传入Input类实例化,会导致不管数字范围是否合法,都会先让用户输入姓名,之后才触发验证器里的循环重新输入数字范围,完全不符合「先验证数字范围再输入姓名」的流程逻辑。
修正后的代码
from pydantic import BaseModel, validator class Input(BaseModel): number_range: str name: str @validator("number_range") def all_numbers_are_valid(cls, value: str) -> str: # 移除空格并拆分输入 string_list = list(map(cls.remove_spaces, value.split(","))) # 校验所有元素是否为数字 if not all(x.isnumeric() for x in string_list): raise ValueError("Invalid characters in range") # 整理为规范格式返回 return ", ".join(string_list) @validator("name") def no_space_name(cls, value: str) -> str: return cls.remove_spaces(value) @staticmethod def remove_spaces(s: str) -> str: return s.strip() def get_valid_number_range() -> str: while True: user_input = input("Enter a range of numbers: ") try: # 通过临时实例化触发Pydantic验证 Input(number_range=user_input, name="temp") return user_input except ValueError as e: print(e) # 先获取合法的数字范围 valid_range = get_valid_number_range() # 再输入姓名 valid_name = input("Enter name: ") # 实例化最终的Input对象 final_input = Input(number_range=valid_range, name=valid_name) print("输入验证通过,最终数据:", final_input.dict())
代码说明
- 拆分输入流程:单独编写
get_valid_number_range函数,循环获取用户输入,直到通过Pydantic验证为止,确保只有数字范围合法后才会进入姓名输入环节。 - 简化验证器职责:移除原验证器内的循环输入逻辑,验证器仅负责格式校验与整理,同时新增
remove_spaces静态方法统一处理空格移除,逻辑更清晰。 - 友好错误提示:利用Pydantic的异常抛出机制,直接返回具体错误信息,用户可明确知晓问题所在。
输入示例演示
Enter a range of numbers: 0,1,a Invalid characters in range Enter a range of numbers: 2, 3,4 Enter name: he llo 输入验证通过,最终数据: {'number_range': '2, 3, 4', 'name': 'hello'}
内容的提问来源于stack exchange,提问作者user18140022
相关产品推荐
相关产品推荐

