Lewati ke isi

Pydantic mendukung banyak tipe umum dari perpustakaan standar Python. Jika Anda memerlukan pemrosesan yang lebih ketat, lihat Strict Types , termasuk jika Anda perlu membatasi nilai yang diizinkan (misalnya memerlukan int positif).

Boolean

Bidang bool standar akan memunculkan ValidationError jika nilainya bukan salah satu dari berikut ini:

  • Boolean yang valid (yaitu True atau False ),
  • Bilangan bulat 0 atau 1 ,
  • str yang bila diubah menjadi huruf kecil adalah salah satunya '0', 'off', 'f', 'false', 'n', 'no', '1', 'on', 't', 'true', 'y', 'yes'
  • satu bytes yang valid sesuai aturan sebelumnya ketika didekodekan ke str

!!! catatan Jika Anda menginginkan logika boolean yang lebih ketat (misalnya bidang yang hanya mengizinkan True dan False ), Anda dapat menggunakan StrictBool .

Berikut ini skrip yang menunjukkan beberapa perilaku ini:

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]
    """

Jenis Tanggal dan Waktu

Pydantic mendukung tipe datetime berikut:

datetime.datetime

  • bidang datetime akan menerima nilai tipe:

    • datetime ; objek datetime yang ada
    • int atau float ; diasumsikan sebagai waktu Unix, yaitu detik (if >= -2e10 dan <= 2e10 ) atau milidetik (if < -2e10 atau > 2e10 ) sejak 1 Januari 1970
    • str ; format berikut diterima:
      • YYYY-MM-DD[T]HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]
      • YYYY-MM-DD diterima dalam mode longgar, tetapi tidak dalam mode ketat
      • int atau float sebagai string (diasumsikan sebagai waktu Unix)
    • datetime.date instance diterima dalam mode longgar, tetapi tidak dalam mode ketat

    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

  • bidang date akan menerima nilai tipe:

    • date ; objek date yang ada
    • int atau float ; ditangani sama seperti yang dijelaskan untuk datetime di atas
    • str ; format berikut diterima:
      • YYYY-MM-DD
      • int atau float sebagai string (diasumsikan sebagai waktu Unix)

    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

  • bidang time akan menerima nilai tipe:

    • time ; objek time yang ada
    • str ; format berikut diterima:
      • 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

  • bidang timedelta akan menerima nilai tipe:

    • timedelta ; objek timedelta yang ada
    • int atau float ; diasumsikan dalam hitungan detik
    • str ; format berikut diterima:
      • [-][DD]D[,][HH:MM:]SS[.ffffff]
        • Contoh: '1d,01:02:03.000004' atau '1D01:02:03.000004' atau '01:02:03'
      • [±]P[DD]DT[HH]H[MM]M[SS]S (format ISO 8601 untuk timedelta)

    from datetime import timedelta

    from pydantic import BaseModel

    class Model(BaseModel): td: timedelta = None

    m = Model(td='P3DT12H30M5S')

    print(m.model_dump())

    >

Jenis Angka

Pydantic mendukung tipe numerik berikut dari perpustakaan standar Python:

int

  • Pydantic menggunakan int(v) untuk memaksa tipe menjadi int ; lihat Konversi data untuk detail tentang hilangnya informasi selama konversi data.

float

  • Pydantic menggunakan float(v) untuk memaksa nilai menjadi float.

enum.IntEnum

  • Validasi: Pydantic memeriksa apakah nilainya adalah instance IntEnum yang valid.
  • Validasi untuk subkelas enum.IntEnum : memeriksa apakah nilainya adalah anggota integer enum yang valid; lihat Enum dan Pilihan untuk lebih jelasnya.

decimal.Decimal

  • Validasi: Pydantic mencoba mengonversi nilai menjadi string, lalu meneruskan string tersebut ke Decimal(v) .
  • Serialisasi: Pydantic membuat serial [Decimal][desimal.Desimal] tipe sebagai string. Anda dapat menggunakan serializer khusus untuk mengganti perilaku ini jika diinginkan. Misalnya:

    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)!

    >

  • Menggunakan model_dump, x dan y tetap merupakan instance dari tipe Decimal

  • Menggunakan model_dump dengan mode='json' , x diserialkan sebagai string , dan y diserialkan sebagai float karena serializer khusus diterapkan.
  • Menggunakan model_dump_json, x diserialkan sebagai string , dan y diserialkan sebagai float karena serializer khusus diterapkan.

Enum

Pydantic menggunakan kelas enum standar Python untuk menentukan pilihan.

enum.Enum memeriksa apakah nilainya adalah instance Enum yang valid. Subkelas enum.Enum memeriksa apakah nilainya adalah anggota enum yang valid.

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]
    """

Daftar dan Tupel

list

Mengizinkan list, tuple, set, frozenset, deque, atau generator dan dilemparkan ke list. Ketika parameter generik disediakan, validasi yang sesuai diterapkan ke semua item dalam daftar.

typing.List

Ditangani sama seperti list di atas.

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

Mengizinkan list, tuple, set, frozenset, deque, atau generator dan dilemparkan ke tuple. Ketika parameter generik disediakan, validasi yang sesuai diterapkan ke masing-masing item tupel

typing.Tuple

Ditangani sama seperti tuple di atas.

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

Subkelas dari typing.NamedTuple mirip dengan tuple , tetapi membuat instance dari kelas namedtuple yang diberikan.

Subkelas dari collections.namedtuple mirip dengan subkelas dari typing.NamedTuple, tetapi karena tipe bidang tidak ditentukan, semua bidang dianggap memiliki tipe [Any][mengetik.Apa pun].

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]
    """

Dek

[deque][koleksi.deque]

Mengizinkan list, tuple, set, frozenset, deque, atau generator dan dilemparkan ke deque. Ketika parameter generik disediakan, validasi yang sesuai diterapkan ke masing-masing item deque .

typing.Deque

Ditangani sama seperti deque di atas.

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])

Set

set

Mengizinkan list, tuple, set, frozenset, deque, atau generator dan dilemparkan ke set. Ketika parameter generik disediakan, validasi yang sesuai diterapkan ke semua item kumpulan.

typing.Set

Ditangani sama seperti yang set di atas.

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

Mengizinkan list, tuple, set, frozenset, deque, atau generator dan dilemparkan ke frozenset. Ketika parameter generik disediakan, validasi yang sesuai diterapkan ke semua item dari kumpulan yang dibekukan.

typing.FrozenSet

Ditangani sama seperti frozenset di atas.

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]

Iterable lainnya

typing.Sequence

Hal ini dimaksudkan untuk digunakan ketika nilai yang diberikan harus memenuhi persyaratan Sequence ABC, dan diinginkan untuk melakukan validasi penuh semangat terhadap nilai-nilai dalam wadah. Perhatikan bahwa ketika validasi harus dilakukan pada nilai kontainer, jenis kontainer mungkin tidak dipertahankan karena validasi mungkin akan menggantikan nilai. Kami menjamin bahwa nilai yang divalidasi akan menjadi [typing.Sequence] yang valid, tetapi mungkin memiliki tipe yang berbeda dari yang diberikan (umumnya akan menjadi list ).

typing.Iterable

Ini dimaksudkan untuk digunakan ketika nilai yang diberikan mungkin merupakan suatu iterable yang tidak boleh digunakan. Lihat Infinite Generator di bawah untuk detail lebih lanjut tentang penguraian dan validasi. Mirip dengan typing.Sequence, kami menjamin bahwa hasil yang divalidasi akan menjadi [typing.Iterable] yang valid], tetapi mungkin memiliki tipe yang berbeda dari yang disediakan. Secara khusus, meskipun tipe non-generator seperti list disediakan, nilai pasca-validasi dari bidang tipe typing.Iterable akan menjadi generator.

Berikut adalah contoh sederhana menggunakan 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)

Generator Tak Terbatas

Jika Anda memiliki generator yang ingin divalidasi, Anda masih dapat menggunakan Sequence seperti dijelaskan di atas. Dalam hal ini, generator akan digunakan dan disimpan pada model sebagai daftar dan nilainya akan divalidasi terhadap parameter tipe Sequence (misalnya int dalam Sequence[int] ).

Namun, jika Anda memiliki generator yang tidak ingin dikonsumsi secara berlebihan (misalnya generator tak terbatas atau pemuat data jarak jauh), Anda dapat menggunakan bidang tipe Iterable:

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

!!! peringatan Selama validasi awal, bidang Iterable hanya melakukan pemeriksaan sederhana bahwa argumen yang diberikan dapat diubah. Untuk mencegahnya dikonsumsi, tidak ada validasi nilai yang dihasilkan yang dilakukan dengan segera.

Meskipun nilai yang dihasilkan tidak divalidasi dengan segera, nilai tersebut masih divalidasi saat dihasilkan, dan akan memunculkan ValidationError pada waktu hasil jika diperlukan:

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]
    """

Jenis Pemetaan

dict

dict(v) digunakan untuk mencoba mengonversi kamus. lihat typing.Dict di bawah untuk batasan subtipe.

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]
    """

DiketikDict

!!! catatan Ini adalah fitur baru dari perpustakaan standar Python pada Python 3.8. Karena keterbatasan dalam typing.TypedDict sebelum 3.12, paket ekstensi pengetikan diperlukan untuk Python <3.12. Anda harus mengimpor TypedDict dari typing_extensions alih-alih typing dan akan mendapatkan kesalahan waktu pembuatan jika tidak melakukannya.

TypedDict mendeklarasikan tipe kamus yang mengharapkan semua instance-nya memiliki sekumpulan kunci tertentu, di mana setiap kunci dikaitkan dengan nilai tipe yang konsisten.

Ini sama dengan dict tetapi Pydantic akan memvalidasi kamus karena kunci diberi anotasi.

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]
    """

Anda dapat mendefinisikan __pydantic_config__ untuk mengubah model yang diwarisi dari TypedDict. Lihat Referensi API ConfigDict untuk detail selengkapnya.

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]
    """

Dapat dihubungi

Lihat di bawah untuk detail selengkapnya tentang penguraian dan validasi

Bidang juga bisa bertipe [Callable][mengetik. Dapat Dipanggil]:

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>

!!! peringatan Bidang yang dapat dipanggil hanya melakukan pemeriksaan sederhana bahwa argumen dapat dipanggil; tidak ada validasi argumen, tipenya, atau tipe kembaliannya yang dilakukan.

Jenis Alamat IP

  • ipaddress.IPv4Address: Menggunakan tipe itu sendiri untuk validasi dengan meneruskan nilai ke IPv4Address(v) .
  • ipaddress.IPv4Interface: Menggunakan tipe itu sendiri untuk validasi dengan meneruskan nilai ke IPv4Address(v) .
  • ipaddress.IPv4Network: Menggunakan tipe itu sendiri untuk validasi dengan meneruskan nilai ke IPv4Network(v) .
  • ipaddress.IPv6Address: Menggunakan tipe itu sendiri untuk validasi dengan meneruskan nilai ke IPv6Address(v) .
  • ipaddress.IPv6Interface: Menggunakan tipe itu sendiri untuk validasi dengan meneruskan nilai ke IPv6Interface(v) .
  • ipaddress.IPv6Network: Menggunakan tipe itu sendiri untuk validasi dengan meneruskan nilai ke IPv6Network(v) .

Lihat Jenis Jaringan untuk jenis alamat IP khusus lainnya.

UUID

Untuk UUID, Pydantic mencoba menggunakan tipe itu sendiri untuk validasi dengan meneruskan nilai ke UUID(v) . Ada fallback ke UUID(bytes=v) untuk bytes dan bytearray .

Jika Anda ingin membatasi versi UUID, Anda dapat memeriksa jenis berikut:

  • UUID1: memerlukan UUID versi 1.
  • UUID3: memerlukan UUID versi 3.
  • UUID4: memerlukan UUID versi 4.
  • UUID5: memerlukan UUID versi 5.

Serikat

Pydantic memiliki dukungan luas untuk validasi gabungan, baik sintaks pipa [typing.Union] dan Python 3.10 ( A | B ) didukung. Baca lebih lanjut di bagian Unions pada dokumen konsep.

[Type][mengetik.Jenis] dan [TypeVar][mengetik.TypeVar]

type

Pydantic mendukung penggunaan type[T] untuk menentukan bahwa suatu bidang hanya dapat menerima kelas (bukan instance) yang merupakan subkelas dari T .

typing.Type

Ditangani sama seperti type di atas.

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]
    """

Anda juga dapat menggunakan Type untuk menentukan bahwa kelas mana pun diperbolehkan.

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 didukung baik tanpa batasan, dengan batasan, atau dengan batasan.

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

Tidak ada Jenis

None, type(None) , atau Literal[None] semuanya setara menurut spesifikasi pengetikan . Hanya mengizinkan nilai None .

string

str : String diterima apa adanya. bytes dan bytearray dikonversi menggunakan v.decode() . Enum s inheriting from str are converted using v.value`. Semua tipe lainnya menyebabkan kesalahan.

String bukanlah Urutan

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] """

Byte

bytes diterima apa adanya. bytearray dikonversi menggunakan bytes(v) . str dikonversi menggunakan v.encode() . int , float , dan Decimal dipaksa menggunakan str(v).encode() . Lihat ByteSize untuk detail selengkapnya.

typing.Literal

Pydantic mendukung penggunaan typing.Literal sebagai cara ringan untuk menentukan bahwa suatu bidang hanya dapat menerima nilai literal tertentu:

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]
    """

Salah satu manfaat dari jenis bidang ini adalah dapat digunakan untuk memeriksa kesetaraan dengan satu atau beberapa nilai spesifik tanpa perlu mendeklarasikan validator khusus:

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]
    """

Dengan pengurutan yang tepat dalam Union yang dianotasi, Anda dapat menggunakan ini untuk mengurai jenis spesifisitas yang menurun:

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 . Apa saja ] []

Mengizinkan nilai apa pun, termasuk None .

typing.Annotated

Mengizinkan membungkus tipe lain dengan metadata arbitrer, sesuai PEP-593 . Petunjuk Annotated mungkin berisi satu panggilan ke fungsi Field , tetapi jika tidak, metadata tambahan akan diabaikan dan tipe root digunakan.

typing.Pattern

Akan menyebabkan nilai input diteruskan ke re.compile(v) untuk membuat pola ekspresi reguler.

pathlib.Path

Cukup gunakan tipe itu sendiri untuk validasi dengan meneruskan nilai ke Path(v) .


本文总阅读量