Python - pydantic 入門介紹與 Models 的簡單使用

小菠蘿測試筆記發表於2021-08-21

前言

為啥要學這個,因為 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()

淺拷貝模型物件

 

相關文章