python - 在使用 pydantic 模型的 python 中,如何使用未知键访问嵌套字典?

标签 python python-typing pydantic

我有一个包含 ID 作为键和数据对象作为值的嵌套字典的数据。我正在尝试将其转换为一个 pydantic 模型。

有时需要访问嵌套值(如果存在)。但是,每次访问嵌套对象时都进行 if 检查非常冗长。例如:

from typing import Dict
from pydantic import BaseModel

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

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

user_dict = {
    'userId': 'abc',
    'events': {
        'xyz': {'eventId': 'xyz', 'eventName': 'User log in'},
        '123': {'eventId': '123', 'eventName': 'User log out'},
    },
}
user = UserModel(**user_dict)
unknown_id = '987'

# Inconvenient access pattern if there are multiple nested ID maps on the way
if user.events.get(unknown_id):
    print(user.events[unknown_id].eventName)

# Compare to the more convenient dict access pattern
print(user_dict['events'].get(unknown_id, {}).get('eventName'))

如果对象很深,使用 if 语句的访问模式会变得非常丑陋。

在使用 pydantic 的过程中,是否有更方便的方法来访问带有 ID 映射的嵌套值?或者有没有一种方法可以在不改变底层数据结构的情况下改进这种虚伪的模型以使其更具可扩展性?

最佳答案

对于“更方便的字典访问模式”的简单翻译,您可以试试这个,它使用 built-in getattr function 的可选默认参数:

getattr(user.events.get(unknown_id), 'eventName', None)

然而,一个更有效的解决方案可能是向 UserModel 添加一个方法,一旦知道不存在具有该 ID 的事件,该方法就会返回。以下建议的解决方案遵循 "Easier to ask for forgiveness than permission"模式。

from typing import Dict
from pydantic import BaseModel

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

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

    def name_of_event_with_id(event_id, default=None):
        try:
            event = self.events[event_id]
        except KeyError:
            return default
        else:
            return event.eventName

关于python - 在使用 pydantic 模型的 python 中,如何使用未知键访问嵌套字典?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69188943/

相关文章:

python - 创建 zip 存档以供即时下载

python - 使用 Apache Beam Python `WriteToFiles` 转换为每个窗口只写入一个文件

python - 什么是变量注解?

python - 如何防止 Pydantic 在 ValidationError 上抛出异常

python - Keras model.predict 与 sigmoid 激活和二元交叉熵只返回 0 或 1,而不是概率

python - 选择排序不理解这段代码

python - Pandas 的 Mypy/typeshed stub

python - 创建自己的可选版本

python - 来自 Pydantic 模型的参数解析器

python - 如何解析一个pydantic模型中的ObjectId?