Zum Inhalt

Experimentelle Funktionen

In diesem Abschnitt finden Sie Dokumentation für neue, experimentelle Funktionen in Pydantic. Diese Funktionen können geändert oder entfernt werden, und wir suchen nach Feedback und Vorschlägen, bevor wir sie zu einem dauerhaften Bestandteil von Pydantic machen.

Weitere Informationen zu experimentellen Funktionen finden Sie in unserer Versionsrichtlinie .

Rückmeldung

Wir freuen uns über Feedback zu experimentellen Funktionen! Bitte öffnen Sie ein Problem im Pydantic GitHub-Repository, um Ihre Gedanken, Wünsche oder Vorschläge mitzuteilen.

Wir empfehlen Ihnen außerdem, vorhandenes Feedback durchzulesen und Ihre Gedanken zu bestehenden Problemen hinzuzufügen.

Warnungen beim Import

Wenn Sie eine experimentelle Funktion aus dem experimental Modul importieren, wird eine Warnmeldung angezeigt, dass die Funktion experimentell ist. Sie können diese Warnung wie folgt deaktivieren:

import warnings

from pydantic import PydanticExperimentalWarning

warnings.filterwarnings('ignore', category=PydanticExperimentalWarning)

Pipeline-API

Pydantic v2.8.0 führte eine experimentelle „Pipeline“-API ein, die das Verfassen von Parsing (Validierung), Einschränkungen und Transformationen auf typsicherere Weise als bestehende APIs ermöglicht. Diese API kann geändert oder entfernt werden. Wir suchen Feedback und Vorschläge, bevor wir sie zu einem dauerhaften Bestandteil von Pydantic machen.

??? API „API-Dokumentation“ pydantic.experimental.pipeline

Im Allgemeinen wird die Pipeline-API verwendet, um eine Abfolge von Schritten zu definieren, die während der Validierung auf eingehende Daten angewendet werden. Die Pipeline-API ist so konzipiert, dass sie typsicherer und zusammensetzbarer ist als die vorhandene Pydantic-API.

Jeder Schritt in der Pipeline kann sein:

  • Ein Validierungsschritt, der eine pydantische Validierung für den bereitgestellten Typ ausführt
  • Ein Transformationsschritt, der die Daten ändert
  • Ein Einschränkungsschritt, der die Daten anhand einer Bedingung prüft
  • Ein Prädikatschritt, der die Daten anhand einer Bedingung prüft und einen Fehler auslöst, wenn er False zurückgibt

Beachten Sie, dass das folgende Beispiel auf Kosten der Komplexität versucht, erschöpfend zu sein: Wenn Sie feststellen, dass Sie so viele Transformationen in Typanmerkungen schreiben, sollten Sie ein UserIn und UserOut Modell (Beispiel unten) oder ein ähnliches Modell in Betracht ziehen, bei dem Sie die Transformationen über idomatic durchführen einfacher Python-Code. Diese APIs sind für Situationen gedacht, in denen die Codeeinsparungen erheblich sind und die zusätzliche Komplexität relativ gering ist.

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)!
    ]
  1. Eine Zeichenfolge in Kleinbuchstaben schreiben.
  2. Beschränken Sie eine Ganzzahl auf einen Wert größer als Null.
  3. Beschränken Sie eine Zeichenfolge so, dass sie mit einem Regex-Muster übereinstimmt.
  4. Sie können auch die Transformations-, Einschränkungs- und Prädikatmethoden der unteren Ebene verwenden.
  5. Verwenden Sie das | oder & -Operatoren zum Kombinieren von Schritten (wie ein logisches ODER oder UND).
  6. Der Aufruf validate_as(...) mit Ellipsis , ... als erstem Positionsargument impliziert validate_as(<field type>) . Verwenden Sie validate_as(Any) um jeden Typ zu akzeptieren.
  7. Bei rekursiven Typen können Sie validate_as_deferred verwenden, um auf den Typ selbst zu verweisen, bevor er definiert wird.
  8. Sie können validate_as() vor oder nach anderen Schritten aufrufen, um eine Vor- oder Nachbearbeitung durchzuführen.

Zuordnung von BeforeValidator , AfterValidator und WrapValidator

Die Methode validate_as ist eine typsicherere Möglichkeit, BeforeValidator , AfterValidator und WrapValidator zu definieren:

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)!
]
  1. Entfernen Sie Leerzeichen aus einer Zeichenfolge, bevor Sie sie als Ganzzahl analysieren.
  2. Multiplizieren Sie eine Ganzzahl mit 2, nachdem Sie sie analysiert haben.
  3. Entfernen Sie Leerzeichen aus einer Zeichenfolge, validieren Sie sie als Ganzzahl und multiplizieren Sie sie dann mit 2.

Alternative Muster

Je nach Szenario stehen viele alternative Muster zur Verfügung. Betrachten Sie als Beispiel das oben erwähnte UserIn und UserOut Muster:

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

In diesem Beispiel wird einfacher idiomatischer Python-Code verwendet, der möglicherweise leichter zu verstehen, leichter zu überprüfen usw. ist als die obigen Beispiele. Welchen Ansatz Sie wählen, sollte wirklich von Ihrem Anwendungsfall abhängen. Um das richtige Muster auszuwählen, müssen Sie die Ausführlichkeit, die Leistung, die Leichtigkeit, mit der Ihren Benutzern bedeutungsvolle Fehler zurückgegeben werden, usw. vergleichen. Achten Sie nur darauf, dass Sie keine erweiterten Muster wie die Pipeline-API missbrauchen, nur weil Sie es können.


本文总阅读量