Экспериментальные возможности¶
В этом разделе вы найдете документацию по новым экспериментальным функциям Pydantic. Эти функции могут быть изменены или удалены, и мы ждем отзывов и предложений, прежде чем сделать их постоянной частью Pydantic.
Дополнительную информацию об экспериментальных функциях см. в нашей Политике версий .
Обратная связь¶
Мы приветствуем отзывы об экспериментальных функциях! Откройте проблему в репозитории Pydantic GitHub, чтобы поделиться своими мыслями, запросами или предложениями.
Мы также рекомендуем вам прочитать существующие отзывы и высказать свои мысли по существующим проблемам.
Предупреждения об импорте¶
Когда вы импортируете экспериментальную функцию из experimental
модуля, вы увидите предупреждающее сообщение о том, что эта функция является экспериментальной. Вы можете отключить это предупреждение следующим образом:
import warnings
from pydantic import PydanticExperimentalWarning
warnings.filterwarnings('ignore', category=PydanticExperimentalWarning)
Конвейерный API¶
В Pydantic v2.8.0 представлен экспериментальный «конвейерный» API, который позволяет выполнять синтаксический анализ (проверку), ограничения и преобразования более типобезопасным способом, чем существующие API. Этот API может быть изменен или удален. Мы ждем отзывов и предложений, прежде чем сделать его постоянной частью Pydantic.
??? API "Документация по API" pydantic.experimental.pipeline
Как правило, API конвейера используется для определения последовательности шагов, которые необходимо применить к входящим данным во время проверки. API конвейера спроектирован так, чтобы быть более типобезопасным и компонуемым, чем существующий API Pydantic.
Каждый шаг конвейера может быть:
- Шаг проверки, который запускает 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 конвейера, только потому, что можете.
本文总阅读量次