您好,登錄后才能下訂單哦!
這篇文章主要介紹了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中定義對象都是通過模型的,你可以認為模型就是類型語言中的類型。
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__ 模型的配置類
可以使用模型本身作為注釋中的類型來定義更復雜的數據結構。
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]
使用 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 目錄加載的值。
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怎么用”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。