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

Pydantic模型中List[Dict]被解析为单个Dict的问题求助

问题:Pydantic模型中Union[str, Dict, List]无法正确解析List[Dict]类型的msg字段

给定以下Pydantic模型:

from typing import Dict, List, Optional, Union
from pydantic import BaseModel

class WSMessage(BaseModel):
    action: str
    success: Optional[bool] = None
    sent_from: Optional[str] = None
    send_to: Optional[str] = None
    data: Optional[Union[str, Dict, List]] = None
    msg: Optional[Union[str, Dict, List]] = None
    reason: Optional[Union[str, Dict, List]] = None
    class Config:
        extra = "allow"

以及测试数据:

data = {
    'action': 'reply',
    'sent_from': 'master',
    'send_to': '192.168.0.100_UE4yWw69iSBEf67JhhWTpg==',
    'data': None,
    'success': True,
    'msg': [
        {'name': 'entry1_name', 'value': 'entry1_value'},
        {'name': 'entry2_name', 'value': 'entry2_value'}
    ],
    'reason': None,
    'to_action': 'get_system_properties',
    'completed': True,
}

将数据加载到模型后,msg字段被错误解析为单个Dict:

>>> msg = WSMessage(**data)
>>> msg.msg
{'name': 'value'}

移除模型中的msg字段后,数据能正确保留为List[Dict]类型。需要让msg字段支持字符串、字典或列表类型,请问问题出在哪里?


原因分析

问题出在Union类型的匹配顺序以及泛型List的定义方式:

  • Pydantic解析Union类型时,会按从左到右的顺序尝试匹配,优先匹配排在前面的类型。
  • 原定义中Dict排在List前面,Pydantic会先尝试将输入的列表解析为Dict。由于列表元素是包含name和value键的字典,Pydantic错误地将这些键值对合并成了一个新Dict(最后一个元素的键覆盖了前面的),最终得到{'name': 'value'}。
  • 直接使用无泛型参数的List,会让Pydantic对列表类型的匹配优先级低于Dict。

解决方案

方案1:调整Union中类型的顺序,将List放在Dict前面

把List移到Dict之前,让Pydantic优先匹配列表类型:

msg: Optional[Union[str, List, Dict]] = None

方案2:使用更具体的泛型类型定义List

明确指定List的元素类型,让Pydantic更准确识别列表类型:

from typing import Any

# 支持任意元素的列表
msg: Optional[Union[str, Dict, List[Any]]] = None

如果确定列表元素都是字典,可以进一步明确:

# 仅支持字典元素的列表
msg: Optional[Union[str, Dict, List[Dict]]] = None

验证效果

修改后的模型加载数据后,msg会正确保留为List[Dict]:

>>> msg = WSMessage(**data)
>>> msg.msg
[{'name': 'entry1_name', 'value': 'entry1_value'}, {'name': 'entry2_name', 'value': 'entry2_value'}]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 06:05:55