前言
為啥要學這個,因為 FastAPI 是基於它進行開發的,而且是個不錯的框架,所以有必要深入學習
前置學習
Python 型別提示:https://www.cnblogs.com/poloyy/p/15145380.html
typing 模組:https://www.cnblogs.com/poloyy/p/15150315.html
Pydantic 介紹
- 使用 python 型別註釋來進行資料校驗和 settings 管理
- pydantic 可以在程式碼執行時強制執行型別提示,並在資料校驗無效時提供友好的錯誤提示
- 定義資料應該如何在規範的 python 程式碼中儲存,然後通過 Python 驗證它
Pydantic 安裝
pip install pydantic
測試 pydantic 是否已編譯
import pydantic print('compiled:', pydantic.compiled) # 輸出結果 compiled: True
Pydantic 注意事項
- pydantic 是一個解析庫,而不是一個驗證庫
- 驗證是達到目的一種手段,構建符合所提供的型別和約束的模型
- 簡單來說:pydantic 保證輸出模型的型別和約束,而不是輸入資料
Models
簡介
- 在 pydantic 中定義物件的主要方法是通過模型(模型是從 BaseModel 繼承的類)
- 所有基於 pydantic 的資料型別本質上都是一個 BaseModel
- 可以將模型視為強型別語言中的型別(比如 Java)
- 不受信任的資料可以傳遞給模型,經過解析和驗證後,pydantic 保證生成的模型例項的欄位將符合定義的欄位型別(例項欄位型別符合類定義的欄位型別)
基礎模型使用
from pydantic import BaseModel class User(BaseModel): id: int name = "小菠蘿測試筆記"
- User 就是一個模型(Models),有兩個欄位(屬性)
- id,整數 int 型別,是必傳的
- name,字串 string 型別,不是必傳,有預設值
為什麼能知道 name 是 string 型別?
因為預設值是 string 型別,因此不需要型別提示( name : string )
注意:當某些欄位沒有型別提示時,需要注意有關欄位順序的警告
宣告一個有效例項
user = User(id='123')
- user 是 User 模型的一個例項物件,就叫模型例項物件吧
- 物件的初始化會執行所有解析和驗證,如果沒有丟擲 ValidationError,證明生成的模型例項是有效的
訪問模型例項物件的屬性
user = User(id='123') print(user.id, type(user.id)) print(user.name, type(user.name)) # 輸出結果 123 <class 'int'> 小菠蘿測試筆記 <class 'str'>
- id 屬性傳的是字串 '123',它會根據模型欄位型別進行轉換為 int
- name 屬性取了預設值
__fields_set__
該變數返回使用者初始化物件時提供了什麼欄位
# __fields_set__ user = User(id='123') print(user.__fields_set__ == {'id'}) print(user.__fields_set__ == {'name'}) user = User(id='123', name="test") print(user.__fields_set__ == {'id', 'name'}) print(user.__fields_set__ == {'id'}) # 輸出結果 True False True False
dict()
可以提供欄位的字典物件
# dict() user = User(id='123') print(user.dict()) print(dict(user)) # 輸出結果 {'id': 123, 'name': '小菠蘿測試筆記'} {'id': 123, 'name': '小菠蘿測試筆記'}
修改模型例項物件的屬性
# 修改模型例項屬性值 user = User(id='123') user.id = 321 print(user.id) # 輸出結果 321
BaseModels 屬性
其實就是 BaseModels 有什麼自帶的方法、屬性
dict()
返回模型欄位和值,字典格式
user = User(id='123', name="test") print(user.dict(), type(user.dict())) # 輸出結果 {'id': 123, 'name': 'test'} <class 'dict'>
json()
返回模型欄位和值,json 字串格式
user = User(id='123', name="test") print(user.json(), type(user.json())) # 輸出結果 {"id": 123, "name": "test"} <class 'str'>
schema()
以 JSON Schema 形式返回模型,字典格式
user = User(id='123', name="test") print(user.schema(), type(user.schema())) # 輸出結果 { "title": "User", "type": "object", "properties": { "id": { "title": "Id", "type": "integer" }, "name": { "title": "Name", "default": "小菠蘿測試筆記", "type": "string" } }, "required": [ "id" ] } <class 'dict'>
schema_json()
以 JSON Schema 形式返回模型,json 字串格式
user = User(id='123', name="test") print(user.schema_json(), type(user.schema_json())) # 輸出結果 { "title": "User", "type": "object", "properties": { "id": { "title": "Id", "type": "integer" }, "name": { "title": "Name", "default": "小菠蘿測試筆記", "type": "string" } }, "required": [ "id" ] } <class 'str'>
copy()
淺拷貝模型物件