实验功能¶
在本节中,您将找到 Pydantic 中新增的、实验性功能的文档。这些功能可能会发生变化或删除,我们在将它们作为 Pydantic 的永久部分之前,正在寻找反馈和建议。
有关实验性功能的更多信息,请查看我们的版本策略。
反馈¶
我们欢迎对实验性功能的反馈!请在 Pydantic GitHub 存储库中打开一个问题,分享您的想法、请求或建议。
我们也鼓励你阅读现有的反馈,并添加你的想法到现有的问题。
进口警示¶
当你从 experimental
模块导入实验性功能时,你会看到一个警告消息,提示该功能是实验性的。你可以使用以下方法禁用此警告:
import warnings
from pydantic import PydanticExperimentalWarning
warnings.filterwarnings('ignore', category=PydanticExperimentalWarning)
管道 API¶
Pydantic v2.8.0 引入了一个实验性的“管道” API,该 API 允许以比现有 API 更类型安全的方式组合解析(验证)、约束和转换。此 API 可能会发生更改或删除,我们在将其作为 Pydantic 的永久部分之前,正在寻找反馈和建议。
通常,管道 API 用于在验证期间定义要应用于传入数据的一系列步骤。管道 API 的设计比现有的 Pydantic API 更具类型安全性和可组合性。
每个管道中的步骤都可以是:
-
对提供的类型运行 pydantic 验证的验证步骤
-
转换步骤,修改数据
-
一个根据条件检查数据的约束步骤
-
一个谓词步骤,该步骤根据条件检查数据,如果返回
False
,则引发错误
请注意,以下示例试图以复杂性为代价进行详尽的尝试:如果您发现自己在类型注释中编写了这么多转换,您可能需要考虑使用 UserIn
和 UserOut
模型(如下例所示)或类似的方法,通过惯用的纯 Python 代码进行转换。这些 API 适用于代码节省显著且增加的复杂性相对较小的情况。
from __future__ import annotations
from datetime import datetime
from typing_extensions import Annotated
from pydantic import BaseModel
from pydantic.experimental.pipeline import validate_as, validate_as_deferred
class User(BaseModel):
name: Annotated[str, validate_as(str).str_lower()] # (1)!
age: Annotated[int, validate_as(int).gt(0)] # (2)!
username: Annotated[str, validate_as(str).str_pattern(r'[a-z]+')] # (3)!
password: Annotated[
str,
validate_as(str)
.transform(str.lower)
.predicate(lambda x: x != 'password'), # (4)!
]
favorite_number: Annotated[ # (5)!
int,
(validate_as(int) | validate_as(str).str_strip().validate_as(int)).gt(
0
),
]
friends: Annotated[list[User], validate_as(...).len(0, 100)] # (6)!
family: Annotated[ # (7)!
list[User],
validate_as_deferred(lambda: list[User]).transform(lambda x: x[1:]),
]
bio: Annotated[
datetime,
validate_as(int)
.transform(lambda x: x / 1_000_000)
.validate_as(...), # (8)!
]
- 将字符串小写。
-
将整数约束为大于零。
-
限制字符串匹配正则表达式模式。
-
你还可以使用较低级别的转换、约束和谓词方法。
-
使用
|
或&
运算符来组合步骤(例如逻辑或或与)。 -
调用
validate_as(...)
时使用Ellipsis
作为第一个位置参数,这意味着validate_as(<field type>)
。使用validate_as(Any)
来接受任何类型。 -
对于递归类型,您可以在定义之前使用
validate_as_deferred
引用自身类型。 -
你可以在其他步骤之前或之后调用
validate_as()
进行预处理或后处理。
从 BeforeValidator
、 AfterValidator
和 WrapValidator
映射¶
validate_as
方法是一种更类型安全的方式来定义 BeforeValidator
、 AfterValidator
和 WrapValidator
:
from typing_extensions import Annotated
from pydantic.experimental.pipeline import transform, validate_as
# BeforeValidator
Annotated[int, validate_as(str).str_strip().validate_as(...)] # (1)!
# AfterValidator
Annotated[int, transform(lambda x: x * 2)] # (2)!
# WrapValidator
Annotated[
int,
validate_as(str)
.str_strip()
.validate_as(...)
.transform(lambda x: x * 2), # (3)!
]
-
在将字符串解析为整数之前,去除其空格。
-
将整数解析后乘以 2。
-
从字符串中删除空格,将其验证为整数,然后乘以 2。
备选模式¶
有许多可供选择的模式,具体取决于场景。仅作为示例,考虑上述的 UserIn
和 UserOut
模式:
from __future__ import annotations
from pydantic import BaseModel
class UserIn(BaseModel):
favorite_number: int | str
class UserOut(BaseModel):
favorite_number: int
def my_api(user: UserIn) -> UserOut:
favorite_number = user.favorite_number
if isinstance(favorite_number, str):
favorite_number = int(user.favorite_number.strip())
return UserOut(favorite_number=favorite_number)
assert my_api(UserIn(favorite_number=' 1 ')).favorite_number == 1
这个示例使用了简洁易懂的 Python 代码,可能比上述示例更容易理解、类型检查等。您选择的方法实际上应该取决于您的用例。您将不得不比较冗长性、性能、向用户返回有意义的错误等,以选择正确的模式。只是要注意不要滥用像管道 API 这样的高级模式,仅仅因为您可以。
本文总阅读量次