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

Pydantic递归实例化模型时如何向子模型传递私有参数

实现方案

核心思路是重写Pydantic提供的实例化后回调钩子,该钩子会在Pydantic完成所有字段的解析、验证、赋值后触发,此时外层ThingList的_api已经赋值完成,内层Thing实例也已经全部创建完成,直接遍历赋值即可。

Pydantic V2 实现

V2官方推荐使用model_post_init作为实例化后自定义操作的钩子,实现代码如下:

from pydantic import BaseModel, PrivateAttr
from typing import List

class Thing(BaseModel):
    _api: Api = PrivateAttr()
    id: int
    name: str

class ThingList(BaseModel):
    _api: API = PrivateAttr()
    __root__: List[Thing]

    def model_post_init(self, __context) -> None:
        # 遍历所有内层Thing实例,传递_api参数
        for thing in self.__root__:
            thing._api = self._api

Pydantic V1 实现

V1对应的钩子方法是__post_init__,实现逻辑完全一致:

from pydantic import BaseModel, PrivateAttr
from typing import List

class Thing(BaseModel):
    _api: Api = PrivateAttr()
    id: int
    name: str

class ThingList(BaseModel):
    _api: API = PrivateAttr()
    __root__: List[Thing]

    def __post_init__(self):
        # 遍历所有内层Thing实例,传递_api参数
        for thing in self.__root__:
            thing._api = self._api

方案优势

  • 无需修改原有实例化逻辑,原来的ThingList(__root__=response, api=api)调用可以完全保留
  • 不依赖全局变量,符合编码规范
  • 完全保留Pydantic原生的字段解析、验证逻辑,后续ThingList新增其他关联属性也不会受影响
  • 可扩展性强,可以把传递逻辑抽成通用基类,所有需要传递_api的嵌套模型都可以继承复用:
# 通用基类示例
class ApiNestedBase(BaseModel):
    _api: API = PrivateAttr()
    def model_post_init(self, __context) -> None:
        # 支持__root__列表类型的属性传递
        if hasattr(self, "__root__") and isinstance(self.__root__, list):
            for item in self.__root__:
                if isinstance(item, BaseModel) and hasattr(item, "_api"):
                    item._api = self._api
        # 支持普通嵌套模型字段的属性传递
        for field_name in self.model_fields:
            field_value = getattr(self, field_name)
            if isinstance(field_value, BaseModel) and hasattr(field_value, "_api"):
                field_value._api = self._api

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 23:39:03