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

Pydantic如何将单键Dict结构分解为包含op_name等字段的Model?

实现方案

可以通过Pydantic的自定义校验+自定义序列化能力实现需求,完全兼容原始输入输出格式的同时,直接暴露三个一级字段,以下分别提供Pydantic v2(主流版本)和Pydantic v1的实现:


Pydantic v2 实现

from pydantic import BaseModel, model_validator, model_serializer

class Model(BaseModel):
    op_name: str
    lvalue: str
    rvalue: str

    # 反序列化逻辑:将原始结构拆解为三个字段
    @model_validator(mode="before")
    @classmethod
    def parse_raw_struct(cls, value):
        if not isinstance(value, dict) or len(value) != 1:
            raise ValueError("输入必须为仅含1个键的字典")
        op_name, expr_list = next(iter(value.items()))
        if not isinstance(expr_list, list) or len(expr_list) != 2:
            raise ValueError("字典值必须为含2个元素的列表")
        return {
            "op_name": op_name,
            "lvalue": expr_list[0],
            "rvalue": expr_list[1]
        }

    # 序列化逻辑:转换回原始结构保证兼容
    @model_serializer()
    def serialize_to_raw_struct(self):
        return {self.op_name: [self.lvalue, self.rvalue]}

效果测试

d = {
    "==": [
        "%var%",
        "10"
    ]
}

# 反序列化
m = Model.model_validate(d)
print(m.op_name) # 输出 ==
print(m.lvalue) # 输出 %var%
print(m.rvalue) # 输出 10

# 序列化,与原始格式完全一致
print(m.model_dump()) # 输出 {'==': ['%var%', '10']}
print(m.model_dump_json()) # 输出 {"==": ["%var%", "10"]}

Pydantic v1 兼容实现

如果使用Pydantic v1版本,可以用以下代码实现相同效果:

from pydantic import BaseModel, root_validator

class Model(BaseModel):
    op_name: str
    lvalue: str
    rvalue: str

    @root_validator(pre=True)
    def parse_raw_struct(cls, value):
        if not isinstance(value, dict) or len(value) != 1:
            raise ValueError("输入必须为仅含1个键的字典")
        op_name, expr_list = next(iter(value.items()))
        if not isinstance(expr_list, list) or len(expr_list) != 2:
            raise ValueError("字典值必须为含2个元素的列表")
        return {
            "op_name": op_name,
            "lvalue": expr_list[0],
            "rvalue": expr_list[1]
        }

    def dict(self, **kwargs):
        return {self.op_name: [self.lvalue, self.rvalue]}

    def json(self, **kwargs):
        return super().json(encoder=lambda obj: obj.dict(), **kwargs)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:06:05