Zum Inhalt

Pydantic unterstützt viele gängige Typen aus der Python-Standardbibliothek. Wenn Sie eine strengere Verarbeitung benötigen, lesen Sie Strict Types , einschließlich der Frage, ob Sie die zulässigen Werte einschränken müssen (z. B. um ein positives int zu erfordern).

Boolesche Werte

Ein Standard bool -Feld löst einen ValidationError aus, wenn der Wert nicht einer der folgenden ist:

  • Ein gültiger boolescher Wert (z. B. True oder False ),
  • Die ganzen Zahlen 0 oder 1 ,
  • Eine str , die, wenn sie in Kleinbuchstaben umgewandelt wird, eine davon ist '0', 'off', 'f', 'false', 'n', 'no', '1', 'on', 't', 'true', 'y', 'yes'
  • a bytes , die gemäß der vorherigen Regel gültig sind, wenn sie in str dekodiert werden

!!! Hinweis Wenn Sie eine strengere boolesche Logik wünschen (z. B. ein Feld, das nur True und False zulässt), können Sie StrictBool verwenden.

Hier ist ein Skript, das einige dieser Verhaltensweisen demonstriert:

from pydantic import BaseModel, ValidationError


class BooleanModel(BaseModel):
    bool_value: bool


print(BooleanModel(bool_value=False))
#> bool_value=False
print(BooleanModel(bool_value='False'))
#> bool_value=False
print(BooleanModel(bool_value=1))
#> bool_value=True
try:
    BooleanModel(bool_value=[])
except ValidationError as e:
    print(str(e))
    """
    1 validation error for BooleanModel
    bool_value
      Input should be a valid boolean [type=bool_type, input_value=[], input_type=list]
    """

Datetime-Typen

Pydantic unterstützt die folgenden Datum/Uhrzeit -Typen:

datetime.datetime

  • datetime Felder akzeptieren Werte des Typs:

    • datetime ; ein vorhandenes datetime Objekt
    • int oder float ; angenommen als Unix-Zeit, also Sekunden (wenn >= -2e10 und <= 2e10 ) oder Millisekunden (wenn < -2e10 oder > 2e10 ) seit dem 1. Januar 1970
    • str ; Folgende Formate werden akzeptiert:
      • YYYY-MM-DD[T]HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]
      • YYYY-MM-DD wird im laxen Modus akzeptiert, jedoch nicht im strikten Modus
      • int oder float als String (angenommen als Unix-Zeit)
    • datetime.date Instanzen werden im laxen Modus akzeptiert, jedoch nicht im strikten Modus

    from datetime import datetime

    from pydantic import BaseModel

    class Event(BaseModel): dt: datetime = None

    event = Event(dt='2032-04-23T10:20:30.400+02:30')

    print(event.model_dump()) """ {'dt': datetime.datetime(2032, 4, 23, 10, 20, 30, 400000, tzinfo=TzInfo(+02:30))} """

datetime.date

  • date akzeptieren Werte des Typs:

    • date ; ein vorhandenes date
    • int oder float ; wird genauso gehandhabt wie oben für datetime beschrieben
    • str ; Folgende Formate werden akzeptiert:
      • YYYY-MM-DD
      • int oder float als String (angenommen als Unix-Zeit)

    from datetime import date

    from pydantic import BaseModel

    class Birthday(BaseModel): d: date = None

    my_birthday = Birthday(d=1679616000.0)

    print(my_birthday.model_dump())

    >

datetime.time

  • time akzeptieren Werte des Typs:

    • time ; ein vorhandenes time
    • str ; Folgende Formate werden akzeptiert:
      • HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]

    from datetime import time

    from pydantic import BaseModel

    class Meeting(BaseModel): t: time = None

    m = Meeting(t=time(4, 8, 16))

    print(m.model_dump())

    >

datetime.timedelta

  • timedelta Felder akzeptieren Werte des Typs:

    • timedelta ; ein vorhandenes timedelta Objekt
    • int oder float ; angenommen, dass es sich um Sekunden handelt
    • str ; Folgende Formate werden akzeptiert:
      • [-][DD]D[,][HH:MM:]SS[.ffffff]
        • Beispiel: '1d,01:02:03.000004' oder '1D01:02:03.000004' oder '01:02:03'
      • [±]P[DD]DT[HH]H[MM]M[SS]S ( ISO 8601- Format für Zeitdelta)

    from datetime import timedelta

    from pydantic import BaseModel

    class Model(BaseModel): td: timedelta = None

    m = Model(td='P3DT12H30M5S')

    print(m.model_dump())

    >

Zahlentypen

Pydantic unterstützt die folgenden numerischen Typen aus der Python-Standardbibliothek:

int

  • Pydantic verwendet int(v) um Typen in ein int umzuwandeln; Einzelheiten zum Informationsverlust während der Datenkonvertierung finden Sie unter Datenkonvertierung .

float

  • Pydantic verwendet float(v) um Werte in Floats umzuwandeln.

enum.IntEnum

  • Validierung: Pydantic prüft, ob der Wert eine gültige IntEnum -Instanz ist.
  • Validierung für die Unterklasse von enum.IntEnum : prüft, ob der Wert ein gültiges Mitglied der Ganzzahl-Enumeration ist; Weitere Einzelheiten finden Sie unter Aufzählungen und Auswahlmöglichkeiten .

decimal.Decimal

  • Validierung: Pydantic versucht, den Wert in eine Zeichenfolge umzuwandeln und übergibt die Zeichenfolge dann an Decimal(v) .
  • Serialisierung: Pydantic serialisiert Decimal-Typen als Strings. Sie können dieses Verhalten bei Bedarf mit einem benutzerdefinierten Serialisierer überschreiben. Zum Beispiel:

    from decimal import Decimal

    from typing_extensions import Annotated

    from pydantic import BaseModel, PlainSerializer

    class Model(BaseModel): x: Decimal y: Annotated[ Decimal, PlainSerializer( lambda x: float(x), return_type=float, when_used='json' ), ]

    my_model = Model(x=Decimal('1.1'), y=Decimal('2.1'))

    print(my_model.model_dump()) # (1)!

    >

    print(my_model.model_dump(mode='json')) # (2)!

    >

    print(my_model.model_dump_json()) # (3)!

    >

  • Bei Verwendung von model_dump bleiben sowohl x als auch y Instanzen des Decimal Typs

  • Bei Verwendung von model_dump mit mode='json' wird x als string serialisiert und y wird aufgrund des angewendeten benutzerdefinierten Serialisierers als float serialisiert.
  • Bei Verwendung von model_dump_json wird x aufgrund des angewendeten benutzerdefinierten Serialisierers als string und y als float serialisiert.

Enum

Pydantic verwendet Pythons Standardklassen enum, um Auswahlmöglichkeiten zu definieren.

enum.Enum prüft, ob der Wert eine gültige Enum -Instanz ist. Die Unterklasse von enum.Enum prüft, ob der Wert ein gültiges Mitglied der Enumeration ist.

from enum import Enum, IntEnum

from pydantic import BaseModel, ValidationError


class FruitEnum(str, Enum):
    pear = 'pear'
    banana = 'banana'


class ToolEnum(IntEnum):
    spanner = 1
    wrench = 2


class CookingModel(BaseModel):
    fruit: FruitEnum = FruitEnum.pear
    tool: ToolEnum = ToolEnum.spanner


print(CookingModel())
#> fruit=<FruitEnum.pear: 'pear'> tool=<ToolEnum.spanner: 1>
print(CookingModel(tool=2, fruit='banana'))
#> fruit=<FruitEnum.banana: 'banana'> tool=<ToolEnum.wrench: 2>
try:
    CookingModel(fruit='other')
except ValidationError as e:
    print(e)
    """
    1 validation error for CookingModel
    fruit
      Input should be 'pear' or 'banana' [type=enum, input_value='other', input_type=str]
    """

Listen und Tupel

list

Ermöglicht list, tuple, set, frozenset, deque oder Generatoren und Umwandlungen in eine list. Wenn ein generischer Parameter angegeben wird, wird die entsprechende Validierung auf alle Elemente der Liste angewendet.

typing.List

Wird wie in der obigen list behandelt.

from typing import List, Optional

from pydantic import BaseModel


class Model(BaseModel):
    simple_list: Optional[list] = None
    list_of_ints: Optional[List[int]] = None


print(Model(simple_list=['1', '2', '3']).simple_list)
#> ['1', '2', '3']
print(Model(list_of_ints=['1', '2', '3']).list_of_ints)
#> [1, 2, 3]

tuple

Ermöglicht list, tuple, set, frozenset, deque oder Generatoren und Umwandlungen in ein tuple. Wenn generische Parameter bereitgestellt werden, wird die entsprechende Validierung auf die jeweiligen Elemente des Tupels angewendet

typing.Tuple

Wird genauso behandelt wie tuple oben.

from typing import Optional, Tuple

from pydantic import BaseModel


class Model(BaseModel):
    simple_tuple: Optional[tuple] = None
    tuple_of_different_types: Optional[Tuple[int, float, bool]] = None


print(Model(simple_tuple=[1, 2, 3, 4]).simple_tuple)
#> (1, 2, 3, 4)
print(Model(tuple_of_different_types=[3, 2, 1]).tuple_of_different_types)
#> (3, 2.0, True)

typing.NamedTuple

Unterklassen von typing.NamedTuple ähneln tuple , erstellen jedoch Instanzen der angegebenen namedtuple -Klasse.

Unterklassen von collections.namedtuple ähneln Unterklassen von typing.NamedTuple, aber da Feldtypen nicht angegeben sind, werden alle Felder so behandelt, als hätten sie den Typ Any.

from typing import NamedTuple

from pydantic import BaseModel, ValidationError


class Point(NamedTuple):
    x: int
    y: int


class Model(BaseModel):
    p: Point


try:
    Model(p=('1.3', '2'))
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    p.0
      Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='1.3', input_type=str]
    """

Deque

deque

Ermöglicht list, tuple, set, frozenset, deque oder Generatoren und Umwandlungen in eine deque. Wenn generische Parameter bereitgestellt werden, wird die entsprechende Validierung auf die entsprechenden Elemente der deque angewendet.

typing.Deque

Wird wie oben deque behandelt.

from typing import Deque, Optional

from pydantic import BaseModel


class Model(BaseModel):
    deque: Optional[Deque[int]] = None


print(Model(deque=[1, 2, 3]).deque)
#> deque([1, 2, 3])

Sets

set

Ermöglicht list, tuple, set, frozenset, deque oder Generatoren und Umwandlungen in ein set. Wenn ein generischer Parameter angegeben wird, wird die entsprechende Validierung auf alle Elemente des Satzes angewendet.

typing.Set

Wird wie oben set behandelt.

from typing import Optional, Set

from pydantic import BaseModel


class Model(BaseModel):
    simple_set: Optional[set] = None
    set_of_ints: Optional[Set[int]] = None


print(Model(simple_set={'1', '2', '3'}).simple_set)
#> {'1', '2', '3'}
print(Model(simple_set=['1', '2', '3']).simple_set)
#> {'1', '2', '3'}
print(Model(set_of_ints=['1', '2', '3']).set_of_ints)
#> {1, 2, 3}

frozenset

Ermöglicht list, tuple, set, frozenset, deque oder Generatoren und Umwandlungen in ein frozenset. Wenn ein generischer Parameter angegeben wird, wird die entsprechende Validierung auf alle Elemente des eingefrorenen Satzes angewendet.

typing.FrozenSet

Die Handhabung entspricht dem oben beschriebenen frozenset .

from typing import FrozenSet, Optional

from pydantic import BaseModel


class Model(BaseModel):
    simple_frozenset: Optional[frozenset] = None
    frozenset_of_ints: Optional[FrozenSet[int]] = None


m1 = Model(simple_frozenset=['1', '2', '3'])
print(type(m1.simple_frozenset))
#> <class 'frozenset'>
print(sorted(m1.simple_frozenset))
#> ['1', '2', '3']

m2 = Model(frozenset_of_ints=['1', '2', '3'])
print(type(m2.frozenset_of_ints))
#> <class 'frozenset'>
print(sorted(m2.frozenset_of_ints))
#> [1, 2, 3]

Andere Iterables

typing.Sequence

Dies ist für den Einsatz vorgesehen, wenn der bereitgestellte Wert die Anforderungen der Sequence ABC erfüllen soll und eine eifrige Validierung der Werte im Container wünschenswert ist. Beachten Sie, dass, wenn eine Validierung der Werte des Containers durchgeführt werden muss, der Typ des Containers möglicherweise nicht erhalten bleibt, da die Validierung möglicherweise dazu führt, dass Werte ersetzt werden. Wir garantieren, dass der validierte Wert eine gültige typing.Sequence ist, er kann jedoch einen anderen Typ als den bereitgestellten haben (im Allgemeinen wird er zu einer list ).

typing.Iterable

Dies ist für die Verwendung gedacht, wenn der bereitgestellte Wert möglicherweise ein iterierbarer Wert ist, der nicht verwendet werden sollte. Weitere Informationen zum Parsen und zur Validierung finden Sie weiter unten unter „Unendliche Generatoren“ . Ähnlich wie bei typing.Sequence garantieren wir, dass das validierte Ergebnis ein gültiges typing.Iterable ist, es kann jedoch einen anderen Typ als den bereitgestellten haben. Insbesondere ist der Nachvalidierungswert eines Felds vom Typ typing.Iterable selbst dann ein Generator, wenn ein Typ bereitgestellt wird, der kein Generator ist, beispielsweise eine list .

Hier ist ein einfaches Beispiel mit typing.Sequence:

from typing import Sequence

from pydantic import BaseModel


class Model(BaseModel):
    sequence_of_ints: Sequence[int] = None


print(Model(sequence_of_ints=[1, 2, 3, 4]).sequence_of_ints)
#> [1, 2, 3, 4]
print(Model(sequence_of_ints=(1, 2, 3, 4)).sequence_of_ints)
#> (1, 2, 3, 4)

Unendliche Generatoren

Wenn Sie einen Generator validieren möchten, können Sie Sequence trotzdem wie oben beschrieben verwenden. In diesem Fall wird der Generator verbraucht und im Modell als Liste gespeichert und seine Werte werden anhand des Typparameters der Sequence validiert (z. B. int in Sequence[int] ).

Wenn Sie jedoch einen Generator haben, den Sie nicht gerne nutzen möchten (z. B. einen unendlichen Generator oder einen Remote-Datenlader), können Sie ein Feld vom Typ Iterable verwenden:

from typing import Iterable

from pydantic import BaseModel


class Model(BaseModel):
    infinite: Iterable[int]


def infinite_ints():
    i = 0
    while True:
        yield i
        i += 1


m = Model(infinite=infinite_ints())
print(m)
"""
infinite=ValidatorIterator(index=0, schema=Some(Int(IntValidator { strict: false })))
"""

for i in m.infinite:
    print(i)
    #> 0
    #> 1
    #> 2
    #> 3
    #> 4
    #> 5
    #> 6
    #> 7
    #> 8
    #> 9
    #> 10
    if i == 10:
        break

!!! Warnung Während der ersten Validierung führen Iterable Felder nur eine einfache Prüfung durch, ob das bereitgestellte Argument iterierbar ist. Um zu verhindern, dass es verbraucht wird, wird keine Validierung der zurückgegebenen Werte durchgeführt.

Obwohl die bereitgestellten Werte nicht eifrig validiert werden, werden sie dennoch validiert, wenn sie bereitgestellt werden, und lösen bei Bedarf einen ValidationError zum Zeitpunkt der Bereitstellung aus:

from typing import Iterable

from pydantic import BaseModel, ValidationError


class Model(BaseModel):
    int_iterator: Iterable[int]


def my_iterator():
    yield 13
    yield '27'
    yield 'a'


m = Model(int_iterator=my_iterator())
print(next(m.int_iterator))
#> 13
print(next(m.int_iterator))
#> 27
try:
    next(m.int_iterator)
except ValidationError as e:
    print(e)
    """
    1 validation error for ValidatorIterator
    2
      Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='a', input_type=str]
    """

Zuordnungstypen

dict

dict(v) wird verwendet, um zu versuchen, ein Wörterbuch zu konvertieren. siehe typing.Dict unten für Subtyp-Einschränkungen.

from pydantic import BaseModel, ValidationError


class Model(BaseModel):
    x: dict


m = Model(x={'foo': 1})
print(m.model_dump())
#> {'x': {'foo': 1}}

try:
    Model(x='test')
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    x
      Input should be a valid dictionary [type=dict_type, input_value='test', input_type=str]
    """

typing.Dict

from typing import Dict

from pydantic import BaseModel, ValidationError


class Model(BaseModel):
    x: Dict[str, int]


m = Model(x={'foo': 1})
print(m.model_dump())
#> {'x': {'foo': 1}}

try:
    Model(x={'foo': '1'})
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    x
      Input should be a valid dictionary [type=dict_type, input_value='test', input_type=str]
    """

TypedDict

!!! Hinweis Dies ist eine neue Funktion der Python-Standardbibliothek ab Python 3.8. Aufgrund von Einschränkungen in typing.TypedDict vor 3.12 ist das typing-extensions- Paket für Python <3.12 erforderlich. Sie müssen TypedDict aus typing_extensions importieren, anstatt typing , und erhalten sonst einen Build-Zeitfehler.

TypedDict deklariert einen Wörterbuchtyp, der erwartet, dass alle seine Instanzen über einen bestimmten Satz von Schlüsseln verfügen, wobei jeder Schlüssel einem Wert eines konsistenten Typs zugeordnet ist.

Es ist dasselbe wie dict, aber Pydantic validiert das Wörterbuch, da die Schlüssel mit Anmerkungen versehen sind.

from typing_extensions import TypedDict

from pydantic import TypeAdapter, ValidationError


class User(TypedDict):
    name: str
    id: int


ta = TypeAdapter(User)

print(ta.validate_python({'name': 'foo', 'id': 1}))
#> {'name': 'foo', 'id': 1}

try:
    ta.validate_python({'name': 'foo'})
except ValidationError as e:
    print(e)
    """
    1 validation error for typed-dict
    id
      Field required [type=missing, input_value={'name': 'foo'}, input_type=dict]
    """

Sie können __pydantic_config__ definieren, um das von TypedDict geerbte Modell zu ändern. Weitere Einzelheiten finden Sie in der ConfigDict API-Referenz.

from typing import Optional

from typing_extensions import TypedDict

from pydantic import ConfigDict, TypeAdapter, ValidationError


# `total=False` means keys are non-required
class UserIdentity(TypedDict, total=False):
    name: Optional[str]
    surname: str


class User(TypedDict):
    __pydantic_config__ = ConfigDict(extra='forbid')

    identity: UserIdentity
    age: int


ta = TypeAdapter(User)

print(
    ta.validate_python(
        {'identity': {'name': 'Smith', 'surname': 'John'}, 'age': 37}
    )
)
#> {'identity': {'name': 'Smith', 'surname': 'John'}, 'age': 37}

print(
    ta.validate_python(
        {'identity': {'name': None, 'surname': 'John'}, 'age': 37}
    )
)
#> {'identity': {'name': None, 'surname': 'John'}, 'age': 37}

print(ta.validate_python({'identity': {}, 'age': 37}))
#> {'identity': {}, 'age': 37}


try:
    ta.validate_python(
        {'identity': {'name': ['Smith'], 'surname': 'John'}, 'age': 24}
    )
except ValidationError as e:
    print(e)
    """
    1 validation error for typed-dict
    identity.name
      Input should be a valid string [type=string_type, input_value=['Smith'], input_type=list]
    """

try:
    ta.validate_python(
        {
            'identity': {'name': 'Smith', 'surname': 'John'},
            'age': '37',
            'email': 'john.smith@me.com',
        }
    )
except ValidationError as e:
    print(e)
    """
    1 validation error for typed-dict
    email
      Extra inputs are not permitted [type=extra_forbidden, input_value='john.smith@me.com', input_type=str]
    """

Abrufbar

Weitere Einzelheiten zum Parsen und Validieren finden Sie weiter unten

Felder können auch vom Typ Callable sein:

from typing import Callable

from pydantic import BaseModel


class Foo(BaseModel):
    callback: Callable[[int], int]


m = Foo(callback=lambda x: x)
print(m)
#> callback=<function <lambda> at 0x0123456789ab>

!!! Warnung: Aufrufbare Felder führen nur eine einfache Prüfung durch, ob das Argument aufrufbar ist. Es wird keine Validierung der Argumente, ihrer Typen oder des Rückgabetyps durchgeführt.

IP-Adresstypen

  • ipaddress.IPv4Address: Verwendet den Typ selbst zur Validierung, indem der Wert an IPv4Address(v) übergeben wird.
  • ipaddress.IPv4Interface: Verwendet den Typ selbst zur Validierung, indem der Wert an IPv4Address(v) übergeben wird.
  • ipaddress.IPv4Network: Verwendet den Typ selbst zur Validierung, indem der Wert an IPv4Network(v) übergeben wird.
  • ipaddress.IPv6Address: Verwendet den Typ selbst zur Validierung, indem der Wert an IPv6Address(v) übergeben wird.
  • ipaddress.IPv6Interface: Verwendet den Typ selbst zur Validierung, indem der Wert an IPv6Interface(v) übergeben wird.
  • ipaddress.IPv6Network: Verwendet den Typ selbst zur Validierung, indem der Wert an IPv6Network(v) übergeben wird.

Weitere benutzerdefinierte IP-Adresstypen finden Sie unter Netzwerktypen .

UUID

Für UUID versucht Pydantic, den Typ selbst zur Validierung zu verwenden, indem der Wert an UUID(v) übergeben wird. Es gibt einen Fallback auf UUID(bytes=v) für bytes und bytearray .

Falls Sie die UUID-Version einschränken möchten, können Sie die folgenden Typen überprüfen:

  • UUID1: erfordert UUID Version 1.
  • UUID3: erfordert UUID Version 3.
  • UUID4: erfordert UUID Version 4.
  • UUID5: erfordert UUID Version 5.

Union

Pydantic bietet umfangreiche Unterstützung für die Union-Validierung, sowohl typing.Union als auch die Pipe-Syntax von Python 3.10 ( A | B ) werden unterstützt. Weitere Informationen finden Sie im Abschnitt Unions “ der Konzeptdokumente.

Type und TypeVar

type

Pydantic unterstützt die Verwendung von type[T] um anzugeben, dass ein Feld nur Klassen (keine Instanzen) akzeptieren darf, die Unterklassen von T sind.

typing.Type

Wird wie oben type behandelt.

from typing import Type

from pydantic import BaseModel, ValidationError


class Foo:
    pass


class Bar(Foo):
    pass


class Other:
    pass


class SimpleModel(BaseModel):
    just_subclasses: Type[Foo]


SimpleModel(just_subclasses=Foo)
SimpleModel(just_subclasses=Bar)
try:
    SimpleModel(just_subclasses=Other)
except ValidationError as e:
    print(e)
    """
    1 validation error for SimpleModel
    just_subclasses
      Input should be a subclass of Foo [type=is_subclass_of, input_value=<class '__main__.Other'>, input_type=type]
    """

Sie können Type auch verwenden, um anzugeben, dass jede Klasse zulässig ist.

from typing import Type

from pydantic import BaseModel, ValidationError


class Foo:
    pass


class LenientSimpleModel(BaseModel):
    any_class_goes: Type


LenientSimpleModel(any_class_goes=int)
LenientSimpleModel(any_class_goes=Foo)
try:
    LenientSimpleModel(any_class_goes=Foo())
except ValidationError as e:
    print(e)
    """
    1 validation error for LenientSimpleModel
    any_class_goes
      Input should be a type [type=is_type, input_value=<__main__.Foo object at 0x0123456789ab>, input_type=Foo]
    """

typing.TypeVar

TypeVar wird entweder uneingeschränkt, eingeschränkt oder mit einer Grenze unterstützt.

from typing import TypeVar

from pydantic import BaseModel

Foobar = TypeVar('Foobar')
BoundFloat = TypeVar('BoundFloat', bound=float)
IntStr = TypeVar('IntStr', int, str)


class Model(BaseModel):
    a: Foobar  # equivalent of ": Any"
    b: BoundFloat  # equivalent of ": float"
    c: IntStr  # equivalent of ": Union[int, str]"


print(Model(a=[1], b=4.2, c='x'))
#> a=[1] b=4.2 c='x'

# a may be None
print(Model(a=None, b=1, c=1))
#> a=None b=1.0 c=1

Keine Typen

None, type(None) oder Literal[None] sind gemäß der Typisierungsspezifikation alle gleichwertig. Erlaubt nur den Wert None .

Saiten

str : Zeichenfolgen werden unverändert akzeptiert. bytes und bytearray werden mit v.decode() konvertiert. s inheriting from Enums are converted using . Alle anderen Typen verursachen einen Fehler.

!!! Warnung „Strings sind keine Sequenzen“

While instances of `str` are technically valid instances of the `Sequence[str]` protocol from a type-checker's point of
view, this is frequently not intended as is a common source of bugs.

As a result, Pydantic raises a `ValidationError` if you attempt to pass a `str` or `bytes` instance into a field of type
`Sequence[str]` or `Sequence[bytes]`:


from typing import Optional, Sequence

from pydantic import BaseModel, ValidationError


class Model(BaseModel):
    sequence_of_strs: Optional[Sequence[str]] = None
    sequence_of_bytes: Optional[Sequence[bytes]] = None


print(Model(sequence_of_strs=['a', 'bc']).sequence_of_strs)
#> ['a', 'bc']
print(Model(sequence_of_strs=('a', 'bc')).sequence_of_strs)
#> ('a', 'bc')
print(Model(sequence_of_bytes=[b'a', b'bc']).sequence_of_bytes)
#> [b'a', b'bc']
print(Model(sequence_of_bytes=(b'a', b'bc')).sequence_of_bytes)
#> (b'a', b'bc')


try:
    Model(sequence_of_strs='abc')
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    sequence_of_strs
      'str' instances are not allowed as a Sequence value [type=sequence_str, input_value='abc', input_type=str]
    """
try:
    Model(sequence_of_bytes=b'abc')
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    sequence_of_bytes
      'bytes' instances are not allowed as a Sequence value [type=sequence_str, input_value=b'abc', input_type=bytes]
    """

Bytes

bytes werden unverändert akzeptiert. bytearray wird mit bytes(v) konvertiert. str werden mit v.encode() konvertiert. int , float und Decimal werden mit str(v).encode() erzwungen. Weitere Informationen finden Sie unter ByteSize .

typing.Literal

Pydantic unterstützt die Verwendung von typing.Literal als einfache Möglichkeit, anzugeben, dass ein Feld nur bestimmte Literalwerte akzeptieren darf:

from typing import Literal

from pydantic import BaseModel, ValidationError


class Pie(BaseModel):
    flavor: Literal['apple', 'pumpkin']


Pie(flavor='apple')
Pie(flavor='pumpkin')
try:
    Pie(flavor='cherry')
except ValidationError as e:
    print(str(e))
    """
    1 validation error for Pie
    flavor
      Input should be 'apple' or 'pumpkin' [type=literal_error, input_value='cherry', input_type=str]
    """

Ein Vorteil dieses Feldtyps besteht darin, dass er zur Prüfung auf Gleichheit mit einem oder mehreren spezifischen Werten verwendet werden kann, ohne dass benutzerdefinierte Validatoren deklariert werden müssen:

from typing import ClassVar, List, Literal, Union

from pydantic import BaseModel, ValidationError


class Cake(BaseModel):
    kind: Literal['cake']
    required_utensils: ClassVar[List[str]] = ['fork', 'knife']


class IceCream(BaseModel):
    kind: Literal['icecream']
    required_utensils: ClassVar[List[str]] = ['spoon']


class Meal(BaseModel):
    dessert: Union[Cake, IceCream]


print(type(Meal(dessert={'kind': 'cake'}).dessert).__name__)
#> Cake
print(type(Meal(dessert={'kind': 'icecream'}).dessert).__name__)
#> IceCream
try:
    Meal(dessert={'kind': 'pie'})
except ValidationError as e:
    print(str(e))
    """
    2 validation errors for Meal
    dessert.Cake.kind
      Input should be 'cake' [type=literal_error, input_value='pie', input_type=str]
    dessert.IceCream.kind
      Input should be 'icecream' [type=literal_error, input_value='pie', input_type=str]
    """

Bei richtiger Reihenfolge in einer annotierten Union können Sie damit Typen mit abnehmender Spezifität analysieren:

from typing import Literal, Optional, Union

from pydantic import BaseModel


class Dessert(BaseModel):
    kind: str


class Pie(Dessert):
    kind: Literal['pie']
    flavor: Optional[str]


class ApplePie(Pie):
    flavor: Literal['apple']


class PumpkinPie(Pie):
    flavor: Literal['pumpkin']


class Meal(BaseModel):
    dessert: Union[ApplePie, PumpkinPie, Pie, Dessert]


print(type(Meal(dessert={'kind': 'pie', 'flavor': 'apple'}).dessert).__name__)
#> ApplePie
print(type(Meal(dessert={'kind': 'pie', 'flavor': 'pumpkin'}).dessert).__name__)
#> PumpkinPie
print(type(Meal(dessert={'kind': 'pie'}).dessert).__name__)
#> Dessert
print(type(Meal(dessert={'kind': 'cake'}).dessert).__name__)
#> Dessert

typing.Any

Erlaubt jeden Wert, einschließlich None .

typing.Annotated

Ermöglicht das Umschließen eines anderen Typs mit beliebigen Metadaten gemäß PEP-593 . Der Annotated -Hinweis kann einen einzelnen Aufruf der Field -Funktion enthalten, ansonsten werden die zusätzlichen Metadaten ignoriert und der Stammtyp verwendet.

typing.Pattern

Führt dazu, dass der Eingabewert an re.compile(v) übergeben wird, um ein reguläres Ausdrucksmuster zu erstellen.

pathlib.Path

Verwendet einfach den Typ selbst zur Validierung, indem der Wert an Path(v) übergeben wird.


本文总阅读量