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

使用Pydantic模型加载序列化嵌套元组遇验证错误求解决方案

解决Pydantic嵌套元组字典键序列化后无法反序列化的问题

针对你遇到的嵌套元组Prop作为字典键,用mode="json"序列化后无法反序列化的问题,最简便的方案是给Prop类型统一绑定序列化/反序列化逻辑,不用在每个模型中重复配置,同时不影响日期等其他类型的JSON序列化处理。

方案一:可靠的嵌套层级区分(推荐)

通过Annotated给Prop类型添加序列化和反序列化规则,用不同分隔符区分嵌套元组层级,避免歧义:

from pydantic import BaseModel, BeforeValidator, PlainSerializer
from typing import Annotated, Tuple

# 自定义Prop类型,内置序列化/反序列化逻辑
Prop = Annotated[
    Tuple[Tuple[str, str], ...],
    # 反序列化:将字符串还原为嵌套元组
    BeforeValidator(
        lambda v: tuple(
            tuple(pair.split(",")) for pair in v.split(",,")
        ) if isinstance(v, str) else v
    ),
    # 序列化:将嵌套元组转为带层级分隔的字符串
    PlainSerializer(
        lambda v: ",,".join(",".join(pair) for pair in v),
        return_type=str
    )
]

class MyModel(BaseModel):
    prop: dict[Prop, list[float]]

# 测试序列化
obj = MyModel(prop={(("a", "A"), ("b", "V")): [0.0, 1.1]})
dumped = obj.model_dump(mode="json")
print(dumped)  # 输出: {'prop': {'a,A,,b,V': [0.0, 1.1]}}

# 测试反序列化
loaded = MyModel(**dumped)
print(loaded.prop)  # 输出: {(('a', 'A'), ('b', 'V')): [0.0, 1.1]}

这种方案通过,,分隔外层元组的元素,用,分隔内层元组的元素,能明确区分嵌套层级,不会出现歧义,适配任意长度的内层元组。

方案二:兼容原有序列化格式(依赖固定内层长度)

如果必须和你之前生成的'a,A,b,V'格式兼容,可基于内层元组固定为2个元素的约定,反序列化时按每2个元素拆分:

from pydantic import BaseModel, BeforeValidator, PlainSerializer
from typing import Annotated, Tuple

Prop = Annotated[
    Tuple[Tuple[str, str], ...],
    # 反序列化:按每2个元素拆分字符串为嵌套元组
    BeforeValidator(
        lambda v: tuple(
            tuple(v.split(",")[i:i+2]) for i in range(0, len(v.split(",")), 2)
        ) if isinstance(v, str) else v
    ),
    # 序列化:保持原有逗号拼接逻辑
    PlainSerializer(
        lambda v: ",".join(item for pair in v for item in pair),
        return_type=str
    )
]

class MyModel(BaseModel):
    prop: dict[Prop, list[float]]

# 测试序列化(和原有格式一致)
obj = MyModel(prop={(("a", "A"), ("b", "V")): [0.0, 1.1]})
dumped = obj.model_dump(mode="json")
print(dumped)  # 输出: {'prop': {'a,A,b,V': [0.0, 1.1]}}

# 测试反序列化
loaded = MyModel(**dumped)
print(loaded.prop)  # 输出: {(('a', 'A'), ('b', 'V')): [0.0, 1.1]}

注意:这种方案仅适用于内层元组长度固定为2的场景,如果后续内层元组元素数量变化,会导致反序列化错误。

方案优势

  • 无需手动在每个模型中写序列化/反序列化逻辑,所有使用Prop的模型自动生效
  • 完全兼容mode="json"的日期处理等其他默认行为
  • 一次定义全局复用,符合你Prop广泛使用的场景

内容的提问来源于stack exchange,提问作者Samuel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 03:20:09