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

如何在Pydantic v2中无需自定义验证实现自定义Serde Schema?

解决方案

要实现你的需求,得给Component类正确实现Pydantic v2的核心Schema——既要支持把Component实例序列化为unique_id字符串,也要支持从unique_id字符串反序列化为Component实例,同时允许直接传入Component实例创建Machine对象。

核心思路

Pydantic的__get_pydantic_core_schema__不能只返回单纯的字符串Schema,得返回一个能处理双向转换的Schema。我们可以用core_schema.no_info_wrap_validator_function包装自定义的验证/转换逻辑,同时指定序列化规则。

完整代码实现

from pydantic import BaseModel, core_schema

class Component:
    def __init__(self, component_id: int):
        self.component_id = component_id

    @property
    def unique_id(self) -> str:
        return f"{type(self).__name__}-{self.component_id}"

    @classmethod
    def parse(cls, unique_id: str):
        return cls(int(unique_id.split("-", 1)[1]))

    @classmethod
    def __get_pydantic_core_schema__(cls, source_type, handler):
        # 处理输入:接受Component实例直接返回,接受字符串则转换为Component
        def validate(value):
            if isinstance(value, Component):
                return value
            elif isinstance(value, str):
                return cls.parse(value)
            else:
                raise ValueError(f"需要Component实例或unique_id字符串,得到的是{type(value)}")

        # 处理输出:把Component实例转为unique_id字符串
        def serialize(value):
            return value.unique_id

        # 构建核心Schema
        return core_schema.no_info_wrap_validator_function(
            validate,
            core_schema.union_schema([
                core_schema.is_instance_schema(Component),
                core_schema.str_schema()
            ]),
            serialization=core_schema.plain_serializer_function_ser_schema(serialize)
        )

class Machine(BaseModel):
    part_1: Component
    part_2: Component
    part_3: Component

# 测试功能
if __name__ == "__main__":
    # 创建Machine实例
    comp1 = Component(101)
    comp2 = Component(102)
    comp3 = Component(103)
    machine = Machine(part_1=comp1, part_2=comp2, part_3=comp3)
    print("原始Machine实例:", machine)

    # 序列化为JSON
    machine_json = machine.model_dump_json(indent=2)
    print("\n序列化后的JSON:")
    print(machine_json)

    # 反序列化恢复实例
    restored_machine = Machine.model_validate_json(machine_json)
    print("\n反序列化后的Machine实例:", restored_machine)
    print("反序列化后组件的unique_id:", restored_machine.part_1.unique_id)

    # 生成JSON Schema
    schema = Machine.model_json_schema()
    print("\nJSON Schema:")
    print(schema)

关键说明

  • validate函数:覆盖了两种输入场景——既接受已有的Component实例直接返回,也接受unique_id字符串并调用parse方法转换为实例,解决了创建Machine时的验证错误问题。
  • serialize函数:明确指定序列化规则,把Component实例转为unique_id字符串,满足输出要求。
  • union_schema:告诉Pydantic这个字段的有效值可以是Component实例或字符串,兼容两种输入方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:37:41