递归模型实例化的Pydantic私有参数



我有一个Pydantic模型,它基本上是其他模型的列表,如下所示:


class Thing(BaseModel):
_api: Api = PrivateAttr()
id: int
name: str
class ThingList(BaseModel):
_api: API = PrivateAttr()
__root__ = List[Thing]

这些东西是从我对外部API调用的JSON内容中解析出来的,例如:

def some_method_somewhere(self, api, **other_args)
...
response = await api.send('GET', url)
return ThingList(__root__=response, api=api)

然而,我不知道如何让Thing模型的Pydantic实例化接收api参数。

我能看到的唯一简单的方法是有一些函数返回一个全局值,我可以从PrivateAttr(default_factory=func)调用,但气味。

此功能应尽可能通用。目前,ThingList可以通过迭代Response对象来替换为一个普通的列表(可以假装它来自请求),但这不能保证将来是真的。(事实上,很可能来自API的其他属性需要集成到ThingList中)。

我梦想的解决方案是在ThingList类的某个地方扩展一个方法,但我找不到Pydantic是如何做到的。

可以在封闭模型的__init__方法中更新嵌套对象的私有属性:

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

class ThingList(BaseModel):
_api: str = PrivateAttr()
__root__: List[Thing]
def __init__(self, *, api, **data):
super().__init__(**data)
self._api = api
for item in self.__root__:
item._api = api