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

如何为第三方类添加Pydantic序列化/反序列化支持?

如何在Pydantic中集成第三方非序列化类(以Numpy数组为例)

当你需要在Pydantic的BaseModel中使用不支持序列化的第三方类(且无法修改其源码)时,可以通过自定义序列化/反序列化函数,并结合Pydantic的字段处理器或自定义类型来实现自动转换。以下是具体实现步骤:

先定义基础的序列化/反序列化函数

假设我们已经针对Numpy数组实现了转换逻辑:

import numpy as np

# 将np.ndarray转为JSON可序列化的字典结构
def serialize_numpy_array(arr: np.ndarray) -> dict:
    return {
        'dtype': str(arr.dtype),
        'shape': arr.shape,
        'data': arr.tobytes().hex()
    }

# 从字典结构还原np.ndarray实例
def deserialize_numpy_array(data: dict) -> np.ndarray:
    dtype = np.dtype(data['dtype'])
    shape = data['shape']
    data_bytes = bytes.fromhex(data['data'])
    return np.frombuffer(data_bytes, dtype=dtype).reshape(shape)

方式一:字段级处理器(适合单个Model字段使用)

直接在BaseModel中为目标字段添加序列化和验证器,指定调用自定义函数:

from pydantic import BaseModel, field_serializer, field_validator

class MySerializableClass(BaseModel):
    foreign_class_instance: np.ndarray

    # 序列化时自动调用自定义函数
    @field_serializer('foreign_class_instance')
    def serialize_foreign(self, value: np.ndarray) -> dict:
        return serialize_numpy_array(value)

    # 反序列化时先处理输入,再验证类型
    @field_validator('foreign_class_instance', mode='before')
    def deserialize_foreign(cls, value: dict | np.ndarray) -> np.ndarray:
        if isinstance(value, np.ndarray):
            return value
        return deserialize_numpy_array(value)

测试代码

# 序列化测试
test_arr = np.array([[1,2,3], [4,5,6]], dtype=np.int32)
model = MySerializableClass(foreign_class_instance=test_arr)
serialized_data = model.model_dump()
# 输出:{'foreign_class_instance': {'dtype': 'int32', 'shape': (2, 3), 'data': '010000000200000003000000040000000500000006000000'}}

# 反序列化测试
restored_model = MySerializableClass.model_validate(serialized_data)
print(restored_model.foreign_class_instance)
# 输出:[[1 2 3]
#        [4 5 6]]

方式二:自定义Pydantic类型(适合多处重复使用)

如果该第三方类需要在多个BaseModel中使用,自定义专属类型可以避免重复代码:

from pydantic import GetCoreSchemaHandler
from pydantic_core import core_schema
from typing import Any

class NumpyArrayType(np.ndarray):
    @classmethod
    def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
        # 定义序列化规则
        serialize_schema = core_schema.plain_serializer_function_ser_schema(
            serialize_numpy_array,
            return_schema=core_schema.dict_schema()
        )
        # 定义反序列化规则
        deserialize_schema = core_schema.no_info_plain_validator_function(deserialize_numpy_array)
        
        # 组合完整Schema:支持直接传入数组或序列化后的字典,输出数组
        return core_schema.json_or_python_schema(
            python_schema=core_schema.is_instance(np.ndarray),
            json_schema=deserialize_schema,
            serialization=serialize_schema,
        )

# 在Model中直接使用自定义类型
class MySerializableClass(BaseModel):
    foreign_class_instance: NumpyArrayType

核心说明

  • mode='before'确保反序列化时先将JSON字典转换为第三方类实例,再进行Pydantic的类型检查。
  • 对于其他第三方类,只需替换示例中的serialize_numpy_array和deserialize_numpy_array为对应的自定义转换函数即可,逻辑完全通用。
  • 上述示例基于Pydantic v2,若使用v1版本,可替换为@validator装饰器和自定义json_encoder。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:18:12