如何给 Pydantic 列表字段一个默认值?

Posted

技术标签:

【中文标题】如何给 Pydantic 列表字段一个默认值?【英文标题】:How to give a Pydantic list field a default value? 【发布时间】:2020-12-26 19:48:04 【问题描述】:

我想创建一个 Pydantic 模型,其中有一个列表字段,未初始化的默认值为空列表。有没有一种惯用的方法来做到这一点?

对于 Python 的内置数据类对象,您可以使用 field(default_factory=list),但是在我自己的实验中,这似乎可以防止我的 Pydantic 模型被腌制。一个简单的实现可能是这样的:

from pydantic import BaseModel

class Foo(BaseModel):
    defaulted_list_field: Sequence[str] = [] # Bad!

但我们都知道不要使用像空列表文字这样的可变值作为默认值。

那么给 Pydantic 列表字段一个默认值的正确方法是什么?

【问题讨论】:

【参考方案1】:

对于 pydantic,您可以使用可变的默认值,例如:

class Foo(BaseModel):
    defaulted_list_field: List[str] = []

f1, f2 = Foo(), Foo()
f1.defaulted_list_field.append("hey!")

print(f1) # defaulted_list_field=['hey!']
print(f2) # defaulted_list_field=[]

它将被正确处理(深拷贝)并且每个模型实例都有自己的空列表。


Pydantic 也有 default_factory parameter。在空列表的情况下,结果将是相同的,而是在声明具有默认值的字段时使用它,您可能希望它是动态的(即每个模型都不同)

from typing import List
from pydantic import BaseModel, Field
from uuid import UUID, uuid4

class Foo(BaseModel):
    defaulted_list_field: List[str] = Field(default_factory=list)
    uid: UUID = Field(default_factory=uuid4)

【讨论】:

"它将被正确处理(深拷贝),每个模型实例都有自己的空列表。"文档中似乎没有提到这一点(我可以找到),但它确实展示了 pydantic 的精心设计。 不知道是因为我使用了 pydantic 的 @dataclass 装饰器,但我得到了 ValueError: mutable default <class 'list'> for field defaulted_list_field is not allowed: use default_factory @dataclass 不允许像标准数据类这样的可变默认字段。 这里的 pydantic 文档中有一个可变默认值的示例:pydantic-docs.helpmanual.io/usage/validators/…。它使用List[int] = []。它没有明确提到它处理可变的默认参数。

以上是关于如何给 Pydantic 列表字段一个默认值?的主要内容,如果未能解决你的问题,请参考以下文章

pydantic学习与使用-3.Typing 类型中的 Optional 和 Union

如何使用列表中的值作为 pydantic 验证器?

建数据库表时给一个字段加可为空和默认值为0的约束该怎么加

如何给Oracle的数据添加默认值

mysql表字段默认值

FastAPI学习-8.POST请求body中添加Field