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

Pydantic序列化自定义Python类报错,如何无需转dataclass实现?

问题解答

这是预期行为吗?

是的,这属于Pydantic的预期行为。Pydantic默认仅支持序列化自身模型类、dataclass以及Python内置基础类型(如str、int、list、dict等)。普通自定义Python类没有内置的序列化规则,Pydantic无法自动解析其内部结构,因此会抛出Unable to serialize unknown type错误。而将普通类转为dataclass后,Pydantic能识别其结构,自然可以正常序列化。

无需修改原类的序列化方案

以下几种方法可以在不改动MyObj类的前提下实现序列化:

1. 为dataclass字段添加序列化器

在MainObj中针对nested字段定义field_serializer,手动将MyObj实例转换为可序列化的字典:

# myobj.py(保持不变)
class MyObj:
    def __init__(self, name: str, value: int):
        self.name = name
        self.value = value
# mwe.py 修改后
from dataclasses import dataclass
from pydantic import TypeAdapter, field_serializer
from myobj import MyObj

@dataclass
class MainObj:
    id: int
    nested: MyObj

    # 针对nested字段的序列化器
    @field_serializer('nested')
    def serialize_nested(self, obj: MyObj) -> dict:
        return {"name": obj.name, "value": obj.value}

MAIN_OBJ_TA = TypeAdapter(MainObj)

obj = MainObj(id=1, nested=MyObj(name="test", value=2))
j = MAIN_OBJ_TA.dump_json(obj)
print(j.decode())

2. 注册全局类型序列化器

如果MyObj在多个场景中被用到,可以给MyObj类型注册全局序列化规则,所有使用该类型的Pydantic场景都能自动序列化:

# mwe.py 修改后
from dataclasses import dataclass
from pydantic import TypeAdapter
from pydantic_core import core_schema
from myobj import MyObj

# 定义MyObj的序列化函数
def serialize_myobj(obj: MyObj) -> dict:
    return {"name": obj.name, "value": obj.value}

# 注册全局序列化规则
core_schema.register_serializer(MyObj, serialize_myobj)

@dataclass
class MainObj:
    id: int
    nested: MyObj

MAIN_OBJ_TA = TypeAdapter(MainObj)

obj = MainObj(id=1, nested=MyObj(name="test", value=2))
j = MAIN_OBJ_TA.dump_json(obj)
print(j.decode())

3. 用Pydantic模型包裹普通类

创建对应MyObj的Pydantic模型,通过转换函数将MyObj实例转为模型实例,间接实现序列化:

# mwe.py 修改后
from dataclasses import dataclass
from pydantic import TypeAdapter, BaseModel
from myobj import MyObj

# 定义对应MyObj的Pydantic模型
class MyObjModel(BaseModel):
    name: str
    value: int

    @classmethod
    def from_myobj(cls, obj: MyObj):
        return cls(name=obj.name, value=obj.value)

@dataclass
class MainObj:
    id: int
    nested: MyObj

# 序列化时先转换为模型
obj = MainObj(id=1, nested=MyObj(name="test", value=2))
serializable_obj = MainObj(id=obj.id, nested=MyObjModel.from_myobj(obj.nested))
MAIN_OBJ_TA = TypeAdapter(MainObj)
j = MAIN_OBJ_TA.dump_json(serializable_obj)
print(j.decode())

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 02:45:54