如何在Pydantic模型中将字符串格式列表转为List[int]类型?
解决Pydantic解析字符串形式列表的问题
针对输入中列表以JSON字符串形式传递的场景,以下几种方案可以在不修改原始输入的前提下,让Pydantic正确解析为List[int]类型:
方案1:使用BeforeValidator预处理字段
利用Pydantic的BeforeValidator,在字段类型校验前将字符串解析为列表:
from typing import List from pydantic import BaseModel, BeforeValidator from json import loads class DigitsResponse(BaseModel): status: str digits: List[int] = BeforeValidator(loads) # 测试代码 json_input = '''{ "status": "OK", "digits": "[4, 6, 3, 6, 8]" }''' response = DigitsResponse.model_validate_json(json_input) print(response.digits) # 输出: [4, 6, 3, 6, 8] print(type(response.digits)) # 输出: <class 'list'>
BeforeValidator会先执行loads函数,把字符串形式的数组转为实际列表,再由Pydantic校验列表元素是否为整数。
方案2:自定义可复用字段类型
如果这类场景需要多次使用,可以自定义字段类型,提升复用性:
from typing import List, Any from pydantic import BaseModel, GetJsonSchemaHandler from pydantic_core import core_schema from json import loads class StringToList: @classmethod def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetJsonSchemaHandler) -> core_schema.CoreSchema: return core_schema.no_info_wrap_validator_function( cls.validate, core_schema.str_schema(), serialization=core_schema.to_string_ser_schema(), ) @classmethod def validate(cls, v: str) -> List[int]: return loads(v) class DigitsResponse(BaseModel): status: str digits: List[int] = StringToList() # 测试代码 json_input = '''{ "status": "OK", "digits": "[4, 6, 3, 6, 8]" }''' response = DigitsResponse.model_validate_json(json_input) print(response.digits) # 输出: [4, 6, 3, 6, 8]
方案3:模型层面全局预处理(Pydantic v2+)
如果需要处理多个字段或复杂逻辑,使用model_validator在模型校验前统一处理输入:
from typing import List from pydantic import BaseModel, model_validator from json import loads class DigitsResponse(BaseModel): status: str digits: List[int] @model_validator(mode='before') def parse_digits(cls, values): if isinstance(values.get('digits'), str): values['digits'] = loads(values['digits']) return values # 测试代码 json_input = '''{ "status": "OK", "digits": "[4, 6, 3, 6, 8]" }''' response = DigitsResponse.model_validate_json(json_input) print(response.digits) # 输出: [4, 6, 3, 6, 8]
异常处理补充
如果输入的字符串可能不是合法JSON数组,可添加异常捕获逻辑,避免程序崩溃:
from json import loads, JSONDecodeError from pydantic import ValidationError, BeforeValidator def safe_parse_list(v): try: return loads(v) except JSONDecodeError: raise ValidationError('digits字段必须是合法的JSON数组字符串') class DigitsResponse(BaseModel): status: str digits: List[int] = BeforeValidator(safe_parse_list)
内容的提问来源于stack exchange,提问作者Patryk Sitarek
相关产品推荐
相关产品推荐

