中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python庫pydantic怎么用

發布時間:2022-03-29 09:08:28 來源:億速云 閱讀:176 作者:小新 欄目:開發技術

這篇文章主要介紹了python庫pydantic怎么用,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

    一、簡介

    pydantic 庫是 python 中用于數據接口定義檢查與設置管理的庫。

    pydantic 在運行時強制執行類型提示,并在數據無效時提供友好的錯誤。

    它具有如下優點:

    • 與 IDE/linter 完美搭配,不需要學習新的模式,只是使用類型注解定義類的實例

    • 多用途,BaseSettings 既可以驗證請求數據,也可以從環境變量中讀取系統設置

    • 快速

    • 可以驗證復雜結構

    • 可擴展,可以使用validator裝飾器裝飾的模型上的方法來擴展驗證

    • 數據類集成,除了BaseModel,pydantic還提供了一個dataclass裝飾器,它創建帶有輸入數據解析和驗證的普通 Python 數據類。

    二、安裝

    pip install pydantic

    要測試 pydantic 是否已編譯,請運行:

    import pydantic
    print('compiled:', pydantic.compiled)

    支持使用dotenv文件獲取配置,需要安裝 python-dotenv

    pip install pydantic[dotenv]

    三、常見模型

    pydantic中定義對象都是通過模型的,你可以認為模型就是類型語言中的類型。

    1、BaseModel 基本模型

    from pydantic import BaseModel
    class User(BaseModel):
        id: int
        name = 'Jane Doe'

    上面的例子,定義了一個User模型,繼承自BaseModel,有2個字段,id是一個整數并且是必需的,name是一個帶有默認值的字符串并且不是必需的

    實例化使用:

    user = User(id='123')

    實例化將執行所有解析和驗證,如果有錯誤則會觸發 ValidationError 報錯。

    模型具有以下屬性:

    • dict() 模型字段和值的字典

    • json() JSON 字符串表示dict()

    • copy() 模型的副本(默認為淺表副本)

    • parse_obj() 使用dict解析數據

    • parse_raw 將str或bytes并將其解析為json,然后將結果傳遞給parse_obj

    • parse_file 文件路徑,讀取文件并將內容傳遞給parse_raw。如果content_type省略,則從文件的擴展名推斷

    • from_orm() 從ORM 對象創建模型

    • schema() 返回模式的字典

    • schema_json() 返回該字典的 JSON 字符串表示

    • construct() 允許在沒有驗證的情況下創建模型

    • __fields_set__ 初始化模型實例時設置的字段名稱集

    • __fields__ 模型字段的字典

    • __config__ 模型的配置類

    2、遞歸模型

    可以使用模型本身作為注釋中的類型來定義更復雜的數據結構。

    from typing import List
    from pydantic import BaseModel
    
    class Foo(BaseModel):
        count: int
        size: float = None
    
    class Bar(BaseModel):
        apple = 'x'
        banana = 'y'
    
    class Spam(BaseModel):
        foo: Foo
        bars: List[Bar]

    3、GenericModel 通用模型(泛型):

    使用 typing.TypeVar 的實例作為參數,傳遞給 typing.Generic,然后在繼承了pydantic.generics.GenericModel 的模型中使用:

    from typing import Generic, TypeVar, Optional, List
    
    from pydantic import BaseModel, validator, ValidationError
    from pydantic.generics import GenericModel
    
    DataT = TypeVar('DataT')
    
    class Error(BaseModel):
        code: int
        message: str
    
    class DataModel(BaseModel):
        numbers: List[int]
        people: List[str]
    
    class Response(GenericModel, Generic[DataT]):
        data: Optional[DataT]
        error: Optional[Error]
    
        @validator('error', always=True)
        def check_consistency(cls, v, values):
            if v is not None and values['data'] is not None:
                raise ValueError('must not provide both data and error')
            if v is None and values.get('data') is None:
                raise ValueError('must provide data or error')
            return v
    
    data = DataModel(numbers=[1, 2, 3], people=[])
    error = Error(code=404, message='Not found')
    
    print(Response[int](data=1))
    #> data=1 error=None
    print(Response[str](data='value'))
    #> data='value' error=None
    print(Response[str](data='value').dict())
    #> {'data': 'value', 'error': None}
    print(Response[DataModel](data=data).dict())
    """
    {
        'data': {'numbers': [1, 2, 3], 'people': []},
        'error': None,
    }
    """
    print(Response[DataModel](error=error).dict())
    """
    {
        'data': None,
        'error': {'code': 404, 'message': 'Not found'},
    }
    """
    try:
        Response[int](data='value')
    except ValidationError as e:
        print(e)
        """
        2 validation errors for Response[int]
        data
          value is not a valid integer (type=type_error.integer)
        error
          must provide data or error (type=value_error)
        """

    4、create_model 動態模型

    在某些情況下,直到運行時才知道模型的結構。為此 pydantic 提供了create_model允許動態創建模型的方法。

    from pydantic import BaseModel, create_model
    DynamicFoobarModel = create_model('DynamicFoobarModel', foo=(str, ...), bar=123)

    四、常用類型

    • None,type(None)或Literal[None]只允許None值

    • bool 布爾類型

    • int 整數類型

    • float 浮點數類型

    • str 字符串類型

    • bytes 字節類型

    • list 允許list,tuple,set,frozenset,deque, 或生成器并轉換為列表

    • tuple 允許list,tuple,set,frozenset,deque, 或生成器并轉換為元組

    • dict 字典類型

    • set 允許list,tuple,set,frozenset,deque, 或生成器和轉換為集合;

    • frozenset 允許list,tuple,set,frozenset,deque, 或生成器和強制轉換為凍結集

    • deque 允許list,tuple,set,frozenset,deque, 或生成器和強制轉換為雙端隊列

    • datetime 的date,datetime,time,timedelta 等日期類型

    • typing 中的 Deque, Dict, FrozenSet, List, Optional, Sequence, Set, Tuple, Union,Callable,Pattern等類型

    • FilePath,文件路徑

    • DirectoryPath 目錄路徑

    • EmailStr 電子郵件地址

    • NameEmail 有效的電子郵件地址或格式

    • PyObject 需要一個字符串并加載可在該虛線路徑中導入的 python 對象;

    • Color 顏色類型

    • AnyUrl 任意網址

    • SecretStr、SecretBytes 敏感信息,將被格式化為'**********'或''

    • Json 類型

    • PaymentCardNumber 支付卡類型

    • 約束類型,可以使用con*類型函數限制許多常見類型的值

      • conlist

    • item_type: Type[T]: 列表項的類型

    • min_items: int = None: 列表中的最小項目數

    • max_items: int = None: 列表中的最大項目數

    • conset

    • item_type: Type[T]: 設置項目的類型

    • min_items: int = None: 集合中的最小項目數

    • max_items: int = None: 集合中的最大項目數

    • conint

    • strict: bool = False: 控制類型強制

    • gt: int = None: 強制整數大于設定值

    • ge: int = None: 強制整數大于或等于設定值

    • lt: int = None: 強制整數小于設定值

    • le: int = None: 強制整數小于或等于設定值

    • multiple_of: int = None: 強制整數為設定值的倍數

    • confloat

    • strict: bool = False: 控制類型強制

    • gt: float = None: 強制浮點數大于設定值

    • ge: float = None: 強制 float 大于或等于設定值

    • lt: float = None: 強制浮點數小于設定值

    • le: float = None: 強制 float 小于或等于設定值

    • multiple_of: float = None: 強制 float 為設定值的倍數

    • condecimal

    • gt: Decimal = None: 強制十進制大于設定值

    • ge: Decimal = None: 強制十進制大于或等于設定值

    • lt: Decimal = None: 強制十進制小于設定值

    • le: Decimal = None: 強制十進制小于或等于設定值

    • max_digits: int = None: 小數點內的最大位數。它不包括小數點前的零或尾隨的十進制零

    • decimal_places: int = None: 允許的最大小數位數。它不包括尾隨十進制零

    • multiple_of: Decimal = None: 強制十進制為設定值的倍數

    • constr

    • strip_whitespace: bool = False: 刪除前尾空格

    • to_lower: bool = False: 將所有字符轉為小寫

    • strict: bool = False: 控制類型強制

    • min_length: int = None: 字符串的最小長度

    • max_length: int = None: 字符串的最大長度

    • curtail_length: int = None: 當字符串長度超過設定值時,將字符串長度縮小到設定值

    • regex: str = None: 正則表達式來驗證字符串

    • conbytes

    • strip_whitespace: bool = False: 刪除前尾空格

    • to_lower: bool = False: 將所有字符轉為小寫

    • min_length: int = None: 字節串的最小長度

    • max_length: int = None: 字節串的最大長度

    • 嚴格類型,您可以使用StrictStr,StrictBytes,StrictInt,StrictFloat,和StrictBool類型,以防止強制兼容類型

    五、驗證器

    使用validator裝飾器可以實現自定義驗證和對象之間的復雜關系。

    from pydantic import BaseModel, ValidationError, validator
    
    class UserModel(BaseModel):
        name: str
        username: str
        password1: str
        password2: str
    
        @validator('name')
        def name_must_contain_space(cls, v):
            if ' ' not in v:
                raise ValueError('must contain a space')
            return v.title()
    
        @validator('password2')
        def passwords_match(cls, v, values, **kwargs):
            if 'password1' in values and v != values['password1']:
                raise ValueError('passwords do not match')
            return v
    
        @validator('username')
        def username_alphanumeric(cls, v):
            assert v.isalnum(), 'must be alphanumeric'
            return v
    
    user = UserModel(
        name='samuel colvin',
        username='scolvin',
        password1='zxcvbn',
        password2='zxcvbn',
    )
    print(user)
    #> name='Samuel Colvin' username='scolvin' password1='zxcvbn' password2='zxcvbn'
    
    try:
        UserModel(
            name='samuel',
            username='scolvin',
            password1='zxcvbn',
            password2='zxcvbn2',
        )
    except ValidationError as e:
        print(e)
        """
        2 validation errors for UserModel
        name
          must contain a space (type=value_error)
        password2
          passwords do not match (type=value_error)
        """

    關于驗證器的一些注意事項:

    • 驗證器是“類方法”,因此它們接收的第一個參數值是UserModel類,而不是UserModel

    • 第二個參數始終是要驗證的字段值,可以隨意命名

    • 單個驗證器可以通過傳遞多個字段名稱來應用于多個字段,也可以通過傳遞特殊值在所有字段上調用單個驗證器'*'

    • 關鍵字參數pre將導致在其他驗證之前調用驗證器

    • 通過each_item=True將導致驗證器被施加到單獨的值(例如List,Dict,Set等),而不是整個對象

    from typing import List
    from pydantic import BaseModel, ValidationError, validator
    
    class ParentModel(BaseModel):
        names: List[str]
    
    class ChildModel(ParentModel):
        @validator('names', each_item=True)
        def check_names_not_empty(cls, v):
            assert v != '', 'Empty strings are not allowed.'
            return v
    
    # This will NOT raise a ValidationError because the validator was not called
    try:
        child = ChildModel(names=['Alice', 'Bob', 'Eve', ''])
    except ValidationError as e:
        print(e)
    else:
        print('No ValidationError caught.')
        #> No ValidationError caught.
    
    
    class ChildModel2(ParentModel):
        @validator('names')
        def check_names_not_empty(cls, v):
            for name in v:
                assert name != '', 'Empty strings are not allowed.'
            return v
    
    try:
        child = ChildModel2(names=['Alice', 'Bob', 'Eve', ''])
    except ValidationError as e:
        print(e)
        """
        1 validation error for ChildModel2
        names
          Empty strings are not allowed. (type=assertion_error)
        """
    • 關鍵字參數 always 將導致始終驗證,出于性能原因,默認情況下,當未提供值時,不會為字段調用驗證器。然而,在某些情況下,始終調用驗證器可能很有用或需要,例如設置動態默認值。

    • allow_reuse 可以在多個字段/模型上使用相同的驗證器

    from pydantic import BaseModel, validator
    
    def normalize(name: str) -> str:
        return ' '.join((word.capitalize()) for word in name.split(' '))
    
    class Producer(BaseModel):
        name: str
    
        # validators
        _normalize_name = validator('name', allow_reuse=True)(normalize)
    
    class Consumer(BaseModel):
        name: str
        # validators
        _normalize_name = validator('name', allow_reuse=True)(normalize)

    六、配置

    如果您創建一個繼承自BaseSettings的模型,模型初始化程序將嘗試通過從環境中讀取,來確定未作為關鍵字參數傳遞的任何字段的值。(如果未設置匹配的環境變量,則仍將使用默認值。)

    這使得很容易:

    • 創建明確定義、類型提示的應用程序配置類

    • 自動從環境變量中讀取對配置的修改

    • 在需要的地方手動覆蓋初始化程序中的特定設置(例如在單元測試中)

    from typing import Set
    
    from pydantic import (
        BaseModel,
        BaseSettings,
        PyObject,
        RedisDsn,
        PostgresDsn,
        Field,
    )
    
    class SubModel(BaseModel):
        foo = 'bar'
        apple = 1
    
    class Settings(BaseSettings):
        auth_key: str
        api_key: str = Field(..., env='my_api_key')
    
        redis_dsn: RedisDsn = 'redis://user:pass@localhost:6379/1'
        pg_dsn: PostgresDsn = 'postgres://user:pass@localhost:5432/foobar'
    
        special_function: PyObject = 'math.cos'
    
        # to override domains:
        # export my_prefix_domains='["foo.com", "bar.com"]'
        domains: Set[str] = set()
    
        # to override more_settings:
        # export my_prefix_more_settings='{"foo": "x", "apple": 1}'
        more_settings: SubModel = SubModel()
    
        class Config:
            env_prefix = 'my_prefix_'  # defaults to no prefix, i.e. ""
            fields = {
                'auth_key': {
                    'env': 'my_auth_key',
                },
                'redis_dsn': {
                    'env': ['service_redis_dsn', 'redis_url']
                }
            }
    
    print(Settings().dict())
    """
    {
        'auth_key': 'xxx',
        'api_key': 'xxx',
        'redis_dsn': RedisDsn('redis://user:pass@localhost:6379/1',
    scheme='redis', user='user', password='pass', host='localhost',
    host_type='int_domain', port='6379', path='/1'),
        'pg_dsn': PostgresDsn('postgres://user:pass@localhost:5432/foobar',
    scheme='postgres', user='user', password='pass', host='localhost',
    host_type='int_domain', port='5432', path='/foobar'),
        'special_function': <built-in function cos>,
        'domains': set(),
        'more_settings': {'foo': 'bar', 'apple': 1},
    }
    """

    支持 Dotenv 文件設置變量,pydantic 有兩種方式加載它:

    class Settings(BaseSettings):
        ...
    
        class Config:
            env_file = '.env'
            env_file_encoding = 'utf-8'

    或者

    settings=Settings(_env_file='prod.env',_env_file_encoding='utf-8')

    即使使用 dotenv 文件,pydantic 仍會讀取環境變量,環境變量將始終優先于從 dotenv 文件加載的值。

    pydantic 支持設置敏感信息文件,同樣有2種方式加載:

    class Settings(BaseSettings):
        ...
        database_password: str
        class Config:
            secrets_dir = '/var/run'

    或者:

    settings = Settings(_secrets_dir='/var/run')

    即使使用 secrets 目錄,pydantic仍會從 dotenv 文件或環境中讀取環境變量,dotenv 文件和環境變量將始終優先于從 secrets 目錄加載的值。

    七、與 mypy 一起使用

    Pydantic 附帶了一個 mypy 插件,向 mypy 添加了許多重要的特定于 pydantic 的功能,以提高其對代碼進行類型檢查的能力。

    例如以下腳本:

    from datetime import datetime
    from typing import List, Optional
    from pydantic import BaseModel, NoneStr
    
    class Model(BaseModel):
        age: int
        first_name = 'John'
        last_name: NoneStr = None
        signup_ts: Optional[datetime] = None
        list_of_ints: List[int]
    
    m = Model(age=42, list_of_ints=[1, '2', b'3'])
    print(m.middle_name)  # not a model field!
    Model()  # will raise a validation error for age and list_of_ints

    在沒有任何特殊配置的情況下,mypy 會捕獲其中一個錯誤:

    13: error: "Model" has no attribute "middle_name"

    啟用插件后,它會同時捕獲:

    13: error: "Model" has no attribute "middle_name"
    16: error: Missing named argument "age" for "Model"
    16: error: Missing named argument "list_of_ints" for "Model"

    要啟用該插件,只需添加pydantic.mypy到mypy 配置文件中的插件列表:

    [mypy]
    plugins = pydantic.mypy

    要更改插件設置的值,請在 mypy 配置文件中創建一個名為 的部分[pydantic-mypy],并為要覆蓋的設置添加鍵值對:

    [mypy]
    plugins = pydantic.mypy
    
    follow_imports = silent
    warn_redundant_casts = True
    warn_unused_ignores = True
    disallow_any_generics = True
    check_untyped_defs = True
    no_implicit_reexport = True
    
    # for strict mypy: (this is the tricky one :-))
    disallow_untyped_defs = True
    
    [pydantic-mypy]
    init_forbid_extra = True
    init_typed = True
    warn_required_dynamic_aliases = True
    warn_untyped_fields = True

    感謝你能夠認真閱讀完這篇文章,希望小編分享的“python庫pydantic怎么用”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    观塘区| 开鲁县| 天峨县| 民权县| 金坛市| 互助| 太和县| 什邡市| 南皮县| 沈阳市| 交城县| 崇州市| 普格县| 迁安市| 夏邑县| 河池市| 嵩明县| 大同县| 宁国市| 东乡| 定州市| 全椒县| 衡阳市| 纳雍县| 永胜县| 株洲市| 万年县| 辽阳县| 都安| 清新县| 灵璧县| 太和县| 彰化县| 长沙市| 中宁县| 诸城市| 樟树市| 观塘区| 扎鲁特旗| 府谷县| 房产|