在 Pydantic 中定义递归模型?

A P*_*oor 18 python oop types jsonschema pydantic

如何定义递归 Pydantic 模型?

这是我的意思的一个例子:

from typing import List
from pydantic import BaseModel

class Task(BaseModel):
    name: str
    subtasks: List[Task] = []
Run Code Online (Sandbox Code Playgroud)

但是当我运行时出现以下错误:

NameError                                 Traceback (most recent call last)
<ipython-input-1-c6dca1d390fe> in <module>
      2 from pydantic import BaseModel
      3
----> 4 class Task(BaseModel):
      5     name: str
      6     subtasks: List[Task] = []

<ipython-input-1-c6dca1d390fe> in Task()
      4 class Task(BaseModel):
      5     name: str
----> 6     subtasks: List[Task] = []
      7

NameError: name 'Task' is not defined
Run Code Online (Sandbox Code Playgroud)

我查看了文档但找不到任何内容。例如,在“递归模型”页面上,但它似乎是关于嵌套子类型而BaseModel不是关于递归类型定义。

感谢您的帮助!

Ale*_*all 14

要么放在from __future__ import annotations文件的顶部,要么将注释更改为List['Task'].

相关的pydantic文档在这里:https ://pydantic-docs.helpmanual.io/usage/postponed_annotations/

但是你的问题中的错误不是特定于 pydantic 的,这就是类型注释的工作原理。


Rya*_*uck 5

扩展亚历克斯·霍尔已接受的答案:

从 Pydantic 文档来看,update_forward_refs()无论是否annotations导入,仍然需要调用。

from typing import List
from pydantic import BaseModel

class Task(BaseModel):
    name: str
    subtasks: List['Task'] = []


Task.update_forward_refs()
Run Code Online (Sandbox Code Playgroud)

或者

# python3.7+
from __future__ import annotations
from typing import List
from pydantic import BaseModel

class Task(BaseModel):
    name: str
    subtasks: List[Task] = []


Task.update_forward_refs()
Run Code Online (Sandbox Code Playgroud)

https://pydantic-docs.helpmanual.io/usage/postponed_annotations/#self-referencing-models