在 Pydantic 中定义递归模型?
Definining recursive models in Pydantic?
如何定义递归 Pydantic 模型?
这是我的意思的一个例子:
from typing import List
from pydantic import BaseModel
class Task(BaseModel):
name: str
subtasks: List[Task] = []
但是当我 运行 我得到以下错误:
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
我查看了文档,但没有找到任何内容。例如,在 "Recursive Models" 上的页面,但它似乎是关于 BaseModel
的嵌套子类型,而不是递归类型定义。
感谢您的帮助!
要么将 from __future__ import annotations
放在文件的顶部,要么将注释更改为 List['Task']
。
相关的 pydantic 文档在这里:https://pydantic-docs.helpmanual.io/usage/postponed_annotations/
但是你问题中的错误不是 pydantic 特有的,这就是类型注释的工作方式。
我发现自己处于一种情况,我想 运行 class 上的根验证器。
发生的情况是,尽管上述解决方案在某些情况下似乎有效,但递归字段 subtasks
的值并未出现在 @root_validator
的 values
字典参数中。
我最终宣布
subtasks: List[Dict]
并在 @root_validator
中递归构建子任务对象:
subtasks = values.get('subtasks')
if subtasks:
values['subtasks']=[Task(**subtask) for subtask in subtasks]
扩展 Alex Hall 接受的答案:
从 Pydantic 文档来看,无论是否导入 annotations
,似乎仍然需要调用 update_forward_refs()
。
from typing import List
from pydantic import BaseModel
class Task(BaseModel):
name: str
subtasks: List['Task'] = []
Task.update_forward_refs()
或
# 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()
https://pydantic-docs.helpmanual.io/usage/postponed_annotations/#self-referencing-models
如何定义递归 Pydantic 模型?
这是我的意思的一个例子:
from typing import List
from pydantic import BaseModel
class Task(BaseModel):
name: str
subtasks: List[Task] = []
但是当我 运行 我得到以下错误:
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
我查看了文档,但没有找到任何内容。例如,在 "Recursive Models" 上的页面,但它似乎是关于 BaseModel
的嵌套子类型,而不是递归类型定义。
感谢您的帮助!
要么将 from __future__ import annotations
放在文件的顶部,要么将注释更改为 List['Task']
。
相关的 pydantic 文档在这里:https://pydantic-docs.helpmanual.io/usage/postponed_annotations/
但是你问题中的错误不是 pydantic 特有的,这就是类型注释的工作方式。
我发现自己处于一种情况,我想 运行 class 上的根验证器。
发生的情况是,尽管上述解决方案在某些情况下似乎有效,但递归字段 subtasks
的值并未出现在 @root_validator
的 values
字典参数中。
我最终宣布
subtasks: List[Dict]
并在 @root_validator
中递归构建子任务对象:
subtasks = values.get('subtasks')
if subtasks:
values['subtasks']=[Task(**subtask) for subtask in subtasks]
扩展 Alex Hall 接受的答案:
从 Pydantic 文档来看,无论是否导入 annotations
,似乎仍然需要调用 update_forward_refs()
。
from typing import List
from pydantic import BaseModel
class Task(BaseModel):
name: str
subtasks: List['Task'] = []
Task.update_forward_refs()
或
# 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()
https://pydantic-docs.helpmanual.io/usage/postponed_annotations/#self-referencing-models