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

Pydantic带pre=True的root_validator接收字典而非输入对象问题

Pydantic中pre=True的root_validator无法检测BaseModel实例的原因及解决方法

问题原因

Pydantic的parse_obj方法处理输入时,会自动将传入的BaseModel实例转换为字段字典(调用实例的dict()方法)。无论是否设置pre=True,root_validator接收的都是转换后的字典,而非原始的A实例,这就是isinstance(values, A)判断始终不生效的核心原因。

解决方法

方法一:重写parse_obj提前拦截A实例

在B类中重写parse_obj类方法,优先判断输入是否为A实例,直接完成结构转换后返回,否则调用父类默认逻辑:

from pydantic import BaseModel

class A(BaseModel):
    a: int
    b: str

class B(BaseModel):
    c: int
    d: str

    @classmethod
    def parse_obj(cls, obj):
        if isinstance(obj, A):
            return cls(c=obj.a, d=obj.b)
        return super().parse_obj(obj)


if __name__ == '__main__':
    a = A(a=1, b='2')
    b = B.parse_obj(a)
    print(b)  # 输出: c=1 d='2'

方法二:在root_validator中检测字典特征转换

若不想重写parse_obj,可通过检测字典中A的特征字段(如a和b)来识别并转换结构:

from pydantic import BaseModel, root_validator

class A(BaseModel):
    a: int
    b: str

class B(BaseModel):
    c: int
    d: str

    @root_validator(pre=True)
    def parse_a_obj(cls, values):
        if 'a' in values and 'b' in values:
            return {'c': values['a'], 'd': values['b']}
        return values


if __name__ == '__main__':
    a = A(a=1, b='2')
    b = B.parse_obj(a)
    print(b)  # 输出: c=1 d='2'

补充说明

如果A和B结构更复杂,方法一的转换逻辑可扩展为批量映射(比如利用obj.dict()匹配字段);方法二的字段检测也可优化为更精准的判断(如校验A的所有字段是否存在于输入字典中)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:10:29