You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pydantic中通用实现字符串/列表字段自动转列表的反序列化逻辑?

自动实现字符串/逗号分隔字符串转列表的Pydantic字段注解

需求背景

我们有手工编辑的YAML配置,其中字段支持三种格式:

  • 单个字符串(如foo: red)
  • 逗号分隔的字符串(如bar: red, green)
  • 标准YAML列表(如qaz: [red, green, blue]或多行列表)

需要将这些字段统一反序列化为Python列表格式,且希望通过字段注解自动触发转换逻辑,无需在每个模型中重复编写model_post_init代码。

解决方案:自定义Pydantic验证器+Annotated注解

利用Pydantic的BeforeValidator和Annotated组合,结合已实现的process_composite_list函数,创建可复用的字段注解。

步骤1:完善转换函数

确保process_composite_list能处理所有输入场景:

def process_composite_list(value):
    if isinstance(value, list):
        return value
    elif isinstance(value, str):
        # 分割逗号并去除元素前后空格,过滤空字符串
        return [item.strip() for item in value.split(',') if item.strip()]
    # 非支持类型抛出错误(可根据需求调整为返回空列表)
    raise ValueError("Unsupported value type for composite list")

步骤2:创建可复用的注解类型

用Annotated封装转换逻辑,形成通用注解:

from typing import Annotated, List
from pydantic import BaseModel, BeforeValidator

# 定义通用复合列表注解,直接在模型字段中引用
CompositeList = Annotated[List[str], BeforeValidator(process_composite_list)]

步骤3:在模型中使用注解

无需编写model_post_init,直接标注字段类型即可:

class ExampleModel(BaseModel):
    foo: CompositeList
    bar: CompositeList
    qaz: CompositeList

class RootModel(BaseModel):
    examples: ExampleModel

步骤4:测试反序列化

加载YAML配置验证结果:

import yaml

# 加载目标YAML内容
yaml_content = """
examples:
  foo: red
  bar: red, green
  qaz: 
    - red
    - green
    - blue
"""

data = yaml.safe_load(yaml_content)
model = RootModel(**data)

# 输出转换后的结果
print(model.model_dump())

输出结果符合预期:

{
  "examples": {
    "foo": ["red"],
    "bar": ["red", "green"],
    "qaz": ["red", "green", "blue"]
  }
}

扩展说明

  • 若需支持其他数据类型(如整数列表),可修改process_composite_list并创建对应注解(如CompositeIntList)
  • 若使用Pydantic v1,可通过@validator(pre=True)装饰器实现类似逻辑,但Annotated方式在v2中更简洁灵活

内容的提问来源于stack exchange,提问作者Tamás Szelei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:57:19