Pydantic中如何将十六进制字符串自动转换为int类型
实现方案
case1运行报错的核心原因是Pydantic默认的int类型转换逻辑仅支持纯数字格式字符串,无法自动识别0x开头的十六进制字符串。Pydantic自带字段前置验证/转换能力,不需要额外实现setter/getter逻辑,通过官方提供的验证器接口就能在默认类型校验前完成格式转换,支持直接传入字典、解析JSON,自动兼容空值场景,不需要逐字段手动处理。
单字段适配写法(少量字段需要转换时使用)
如果只有个别字段需要支持十六进制字符串转int,直接给对应字段加前置验证器即可,示例代码:
from pydantic import BaseModel, field_validator from typing import Optional data = { "aaa" : 4, "bbb" : "0x3", "ccc": None # 兼容空值场景 } class DataTemp(BaseModel): aaa : int bbb : Optional[int] ccc: Optional[int] # mode='before' 表示逻辑在默认类型校验之前执行 @field_validator('bbb', 'ccc', mode='before') def hex_str_to_int(cls, v): # 空值直接返回,交给Optional类型规则处理 if v is None: return v # 输入本身是int类型时直接放行 if isinstance(v, int): return v # 字符串类型按十六进制格式解析 if isinstance(v, str): return int(v, 16) raise ValueError(f"不支持的数值类型: {type(v)}") def main(): _data = DataTemp(**data) print(_data) # 输出结果:aaa=4 bbb=3 ccc=None # 直接解析JSON也可正常使用:DataTemp.model_validate_json(待解析JSON字符串) if __name__ == "__main__": main()
如果你使用的是Pydantic v1版本,将
field_validator替换为validator,去掉参数mode='before'并替换为pre=True即可,转换逻辑完全一致。
全局自定义类型写法(大量字段需要转换时使用)
如果有多个字段都需要支持十六进制字符串自动转int,不需要给每个字段单独加验证器,可以自定义通用数值类型,所有标注为该类型的字段都会自动具备转换能力:
from pydantic import BaseModel, GetCoreSchemaHandler from pydantic_core import CoreSchema, core_schema from typing import Optional, Any # 自定义支持十六进制字符串转换的int类型 class HexInt(int): @classmethod def __get_pydantic_core_schema__( cls, source_type: Any, handler: GetCoreSchemaHandler ) -> CoreSchema: def parse_value(v): if v is None: return None if isinstance(v, int): return cls(v) if isinstance(v, str): return cls(v, 16) raise ValueError(f"无法将{type(v)}类型转换为数值") return core_schema.no_info_plain_validator_function( parse_value, serialization=core_schema.plain_serializer_function_ser_schema(lambda x: int(x)), ) # 所有需要支持十六进制转换的字段直接标注HexInt类型即可 class DataTemp(BaseModel): aaa : HexInt bbb : Optional[HexInt] ccc: Optional[HexInt]
使用该方式后,无论传入正常int值、0x开头的十六进制字符串、还是None空值,都能自动完成转换校验,直接传字典、调用model_validate/model_validate_json接口解析数据都不需要手动做额外处理。
补充说明
- 如果需要兼容不带
0x前缀的十六进制字符串,只需要在parse_value的字符串处理分支中增加格式判断,调整对应解析规则即可。 - 验证器逻辑会自动收集校验错误,传入非法格式值时会和Pydantic原生校验错误抛出格式保持一致,不需要额外做异常适配。
内容的提问来源于stack exchange,提问作者Jmob
相关产品推荐
相关产品推荐

