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

为何Pydantic将Json[Any]|str字段按字符串校验?如何返回字典?

Pydantic Union类型解析差异原因及解决方案

原因分析

Pydantic处理Union类型时,会按类型声明的顺序依次尝试匹配输入值:

  • 对于Json[Any] | str:输入的JSON格式字符串本身就是合法的str类型,无需转换就能匹配成功,因此Pydantic直接将其保留为字符串类型,不会触发后续的JSON解析逻辑。
  • 对于Json[Any] | int:输入的字符串无法转换为int类型(转换失败),Pydantic才会继续尝试下一个类型Json[Any],此时会自动将JSON字符串解析为对应的字典类型。

解决方案

如果需要让Json[Any] | str的场景优先尝试解析JSON字符串为字典,仅当解析失败时才保留字符串,可以通过自定义前置验证器实现:

from typing import Any
from json import loads, JSONDecodeError
from pydantic import BaseModel, Json, BeforeValidator

def try_parse_json(value: Any) -> Any:
    # 仅对字符串尝试JSON解析
    if isinstance(value, str):
        try:
            return loads(value)
        except JSONDecodeError:
            # 解析失败则返回原字符串
            pass
    return value

class FooStr(BaseModel):
    json_or_str: Json[Any] | str = BeforeValidator(try_parse_json)

if __name__ == "__main__":
    print(type(FooStr(json_or_str='{"a": 1}').json_or_str))  # 输出 <class 'dict'>
    print(type(FooStr(json_or_str='plain text').json_or_str))  # 输出 <class 'str'>

这个验证器会先尝试将输入的字符串解析为JSON对象,解析失败时再保留原字符串,从而实现预期的优先级逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:12:35