用pydantic指定嵌套字典的最佳方法?

Posted

技术标签:

【中文标题】用pydantic指定嵌套字典的最佳方法?【英文标题】:Best way to specify nested dict with pydantic? 【发布时间】:2020-11-25 04:43:07 【问题描述】:

上下文

我正在尝试使用pydantic 验证/解析一些数据。

我想指定字典可以有一个键daytime,或者没有。 如果是这样,我希望daytime 的值包括sunrisesunset

例如这些应该是允许的:


   'type': 'solar',
   'daytime': 
      'sunrise': 4, # 4am
      'sunset': 18 # 6pm
   


   'type': 'wind'
   # daytime key is omitted


   'type': 'wind',
   'daytime': None

但我想验证失败


   'type': 'solar',
   'daytime': 
      'sunrise': 4
   

因为它有一个daytime 值,但没有日落值。

MWE

我有一些代码可以做到这一点。 如果我运行这个脚本,它就会成功执行。

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

class DayTime(BaseModel):
    sunrise: int
    sunset: int
    
class Plant(BaseModel):
    daytime: Optional[DayTime] = None
    type: str

p = Plant.parse_obj('type': 'wind')
p = Plant.parse_obj('type': 'wind', 'daytime': None)
p = Plant.parse_obj(
    'type': 'solar', 
    'daytime': 
        'sunrise': 5, 
        'sunset': 18
    )
    
try:
    p = Plant.parse_obj(
        'type': 'solar', 
        'daytime': 
            'sunrise': 5
        )
except ValidationError:
    pass
else:
    raise AssertionError("Should have failed")

问题

我想知道的是, 这就是你应该使用 pydantic 处理嵌套数据的方式吗?

我有很多嵌套层,这似乎有点冗长。

有什么方法可以做的更简洁,比如:

class Plant(BaseModel):
    daytime: Optional[Dict[('sunrise', 'sunset'), int]] = None
    type: str

【问题讨论】:

【参考方案1】:

Pydantic create_model 功能正是您所需要的:

from pydantic import BaseModel, create_model

class Plant(BaseModel):
    daytime: Optional[create_model('DayTime', sunrise=(int, ...), sunset=(int, ...))] = None
    type: str

【讨论】:

有什么办法让它不输入?只说dict的dict? @Nickpick 如果您不想进一步输入,您可以简单地将 dict 声明为白天的类型,如下所示:daytime: dict

以上是关于用pydantic指定嵌套字典的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

实现嵌套字典的最佳方法是啥?

python 在多行上访问嵌套字典的最佳PEP-8实践是什么?

用 setState() 更新嵌套的 React 状态属性的最佳选择是啥?

将具有嵌套对象的对象保存到文件的最佳方法?

打破 JavaScript 中嵌套循环的最佳方法是啥?

从嵌套的 javascript 对象中删除属性的最佳方法是啥?