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

Python使用Pydantic模型时如何便捷访问键未知的嵌套字典

解决方案

方案1:给Pydantic基类扩展通用get方法(推荐)

无需修改现有业务模型的字段结构,全项目复用性最高,完全兼容原生字典的链式get访问习惯:

from typing import Any, Dict, Optional
from pydantic import BaseModel

class BaseModelWithGet(BaseModel):
    def get(self, key: str, default: Any = None) -> Any:
        value = getattr(self, key, default)
        if isinstance(value, dict):
            return _DictWithGet(value)
        if isinstance(value, BaseModelWithGet):
            return value
        return value

class _DictWithGet(dict):
    def get(self, key: str, default: Any = None) -> Any:
        value = super().get(key, default)
        if isinstance(value, BaseModelWithGet):
            return value
        if isinstance(value, dict):
            return _DictWithGet(value)
        return value

原有业务模型只需要调整继承的父类即可:

class EventModel(BaseModelWithGet):
    eventId: str
    eventName: str

class UserModel(BaseModelWithGet):
    userId: str
    events: Dict[str, EventModel]

使用效果和原生字典完全一致:

unknown_id = '987'
# 不存在的ID直接返回默认值,无需额外判断
event_name = user.get("events", {}).get(unknown_id, {}).get("eventName", "未知事件")
print(event_name) # 输出:未知事件
# 存在的ID正常取值
event_name = user.get("events", {}).get("xyz", {}).get("eventName", "未知事件")
print(event_name) # 输出:User log in

方案2:临时转字典访问

如果不想调整现有模型定义,仅需单次访问嵌套值,可直接将Pydantic模型转成原生字典后使用链式get:

# Pydantic V2 写法
event_name = user.model_dump()["events"].get(unknown_id, {}).get("eventName")
# Pydantic V1 写法
event_name = user.dict()["events"].get(unknown_id, {}).get("eventName")

方案3:定制ID映射字典返回空模型

如果固定某类ID映射的模型结构确定,可以自定义字典类,访问不存在的键时自动返回空模型,进一步简化访问写法:

from typing import TypeVar, Dict
from pydantic import BaseModel, field_validator

T = TypeVar('T', bound=BaseModel)

class IDMap(Dict[str, T]):
    def __init__(self, model_type: type[T], *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.model_type = model_type

    def __getitem__(self, key: str) -> T:
        return self.get(key, self.model_type())

# 业务模型调整字段类型
class UserModel(BaseModel):
    userId: str
    events: IDMap[EventModel]

    @field_validator('events', mode='before')
    def validate_events(cls, v):
        return IDMap(EventModel, v)

使用时直接访问不会抛出KeyError:

# 不存在的ID返回空EventModel,若EventModel字段设置了默认值会直接读取默认值
print(user.events[unknown_id].eventName)

方案选型参考

  • 方案1适配性最高,支持任意层级的嵌套模型,无需针对单个字段做特殊处理
  • 方案2改动量最小,适合临时单次使用场景
  • 方案3访问写法最简洁,仅适合固定结构的ID映射场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:24:05