<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
pydantic 庫是 python 中用於資料介面定義檢查與設定管理的庫。
pydantic 在執行時強制執行型別提示,並在資料無效時提供友好的錯誤。
它具有如下優點:
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*型別函數限制許多常見型別的值
嚴格型別,您可以使用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) """
關於驗證器的一些注意事項:
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) """
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簡易入門的文章就介紹到這了,更多相關python庫pydantic教學內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45