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

如何用Pydantic验证深度嵌套数据结构并简化嵌套类?

问题

我有如下深度嵌套的数据结构:

{
  "code": 123,
  "a": {
    "b": {
      "c": {
        "d": {
          "value": "hello world"
        }
      }
    }
  }
}

我希望用Pydantic验证该结构,并访问code和value字段,仅关注根层级和最内层的核心数据。目前我通过创建多层辅助模型类实现需求:

from pydantic import BaseModel

sample = {"code": 123, "a": {"b": {"c": {"d": {"value": "hello world"}}}}}


class D(BaseModel):
    value: str


class C(BaseModel):
    d: D


class B(BaseModel):
    c: C


class A(BaseModel):
    b: B


class MyModel(BaseModel):
    code: int
    a: A


obj = MyModel(**sample)
print(obj.code, obj.a.b.c.d.value)

请问是否存在方法可以简化从a到d的嵌套层级,从而减少所需的辅助类数量?


简化方案

1. 直接映射深层字段(Pydantic v2+ 推荐)

使用Pydantic v2引入的AliasPath,可以直接在根模型中将深层的value字段映射为根模型的属性,完全省略中间模型类:

from pydantic import BaseModel, Field, AliasPath

sample = {"code": 123, "a": {"b": {"c": {"d": {"value": "hello world"}}}}}

class MyModel(BaseModel):
    code: int
    value: str = Field(validation_alias=AliasPath("a", "b", "c", "d", "value"))

obj = MyModel(**sample)
print(obj.code, obj.value)  # 无需多层嵌套,直接访问obj.value

这种方式既保留了完整的验证逻辑,又能直接通过根模型访问核心字段,是最简洁的解决方案。

2. 嵌套定义内部模型

如果需要保留原始嵌套结构的访问路径,但不想创建全局范围的辅助类,可以在根模型内部嵌套定义子模型:

from pydantic import BaseModel

sample = {"code": 123, "a": {"b": {"c": {"d": {"value": "hello world"}}}}}

class MyModel(BaseModel):
    code: int
    
    class A(BaseModel):
        class B(BaseModel):
            class C(BaseModel):
                class D(BaseModel):
                    value: str
                    
        b: B
        
    a: A

obj = MyModel(**sample)
print(obj.code, obj.a.b.c.d.value)

这种方式把所有子模型都封装在根模型内部,不会污染全局命名空间,同时保持原有的访问路径。

3. 用dict类型结合自定义验证(适合简单场景)

如果只需要验证核心字段,对中间层级结构要求不高,可以将a字段定义为dict类型,再通过root_validator提取value:

from pydantic import BaseModel, root_validator
from typing import Dict

sample = {"code": 123, "a": {"b": {"c": {"d": {"value": "hello world"}}}}}

class MyModel(BaseModel):
    code: int
    a: Dict
    value: str = None

    @root_validator(pre=True)
    def extract_value(cls, values):
        try:
            values["value"] = values["a"]["b"]["c"]["d"]["value"]
        except KeyError:
            raise ValueError("Missing required 'value' field in nested structure")
        return values

obj = MyModel(**sample)
print(obj.code, obj.value)

这种方式灵活性较高,但需要自行处理路径存在性的异常,验证逻辑相对手动。


内容的提问来源于stack exchange,提问作者Pēteris Caune

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:53:20