0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

Pydantic:強大的數(shù)據(jù)校驗工具

科技綠洲 ? 來源:Python實用寶典 ? 作者:Python實用寶典 ? 2023-10-30 11:40 ? 次閱讀

Pydantic 是一個使用Python類型注解進行數(shù)據(jù)驗證和管理的模塊。安裝方法非常簡單,打開終端輸入:

pip install pydantic

它類似于 Django DRF 序列化器的數(shù)據(jù)校驗功能,不同的是,Django里的序列化器的Field是有限制的,如果你想要使用自己的Field還需要繼承并重寫它的基類:

# Django 序列化器的一個使用例子,你可以和下面Pydantic的使用作對比
class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    author = models.CharField(max_length=32)
    publish = models.CharField(max_length=32)

而 Pydantic 基于Python3.7以上的類型注解特性,實現(xiàn)了可以對任何類做數(shù)據(jù)校驗的功能:

上滑查看更多代碼

# Pydantic 數(shù)據(jù)校驗功能
from datetimeimport datetime
from typingimport List, Optional
from pydanticimport BaseModel


class User(BaseModel):
id: int
name ='John Doe'
signup_ts: Optional[datetime] =None
friends: List[int] = []


external_data = {
'id':'123',
'signup_ts':'2019-06-01 12:22',
'friends': [1,2,'3'],
}
user = User(**external_data)
print(user.id)
print(type(user.id))
# > 123
# > < class 'int' >
print(repr(user.signup_ts))
# > datetime.datetime(2019, 6, 1, 12, 22)
print(user.friends)
# > [1, 2, 3]
print(user.dict())
"""
{
'id': 123,
'signup_ts': datetime.datetime(2019, 6, 1, 12, 22),
'friends': [1, 2, 3],
'name': 'John Doe',
}
"""

從上面的基本使用可以看到,它甚至能自動幫你做數(shù)據(jù)類型的轉(zhuǎn)換,比如代碼中的 user.id, 在字典中是字符串,但經(jīng)過Pydantic校驗器后,它自動變成了int型,因為User類里的注解就是int型。

當我們的數(shù)據(jù)和定義的注解類型不一致時會報這樣的Error:

from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel


class User(BaseModel):
    id: int
    name = 'John Doe'
    signup_ts: Optional[datetime] = None
    friends: List[int] = []


external_data = {
    'id': '123',
    'signup_ts': '2019-06-01 12:222',
    'friends': [1, 2, '3'],
}
user = User(**external_data)
"""
Traceback (most recent call last):
  File "1.py", line 18, in < module >
    user = User(**external_data)
  File "pydanticmain.py", line 331, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for User
signup_ts
  invalid datetime format (type=value_error.datetime)
"""

即 "invalid datetime format", 因為我傳入的 signup_ts 不是標準的時間格式(多了個2)。

1. Pydantic模型數(shù)據(jù)導出 ****

通過Pydantic模型中自帶的 json 屬性方法,能讓經(jīng)過校驗后的數(shù)據(jù)一行命令直接轉(zhuǎn)成 json 字符串,如前文中的 user 對象:

print(user.dict()) # 轉(zhuǎn)為字典
"""
{
    'id': 123,
    'signup_ts': datetime.datetime(2019, 6, 1, 12, 22),
    'friends': [1, 2, 3],
    'name': 'John Doe',
}
"""
print(user.json()) # 轉(zhuǎn)為json
"""
{"id": 123, "signup_ts": "2019-06-01T12:22:00", "friends": [1, 2, 3], "name": "John Doe"}
"""

非常方便。它還支持將整個數(shù)據(jù)結(jié)構(gòu)導出為 schema json,它能完整地描述整個對象的數(shù)據(jù)結(jié)構(gòu)類型:

上滑查看更多代碼

print(user.schema_json(indent=2))
"""
{
"title": "User",
"type": "object",
"properties": {
"id": {
"title": "Id",
"type": "integer"
},
"signup_ts": {
"title": "Signup Ts",
"type": "string",
"format": "date-time"
},
"friends": {
"title": "Friends",
"default": [],
"type": "array",
"items": {
"type": "integer"
}
},
"name": {
"title": "Name",
"default": "John Doe",
"type": "string"
}
},
"required": [
"id"
]
}
"""

2.數(shù)據(jù)導入

除了直接定義數(shù)據(jù)校驗模型,它還能通過ORM、字符串、文件導入到數(shù)據(jù)校驗模型:

比如字符串(raw):

from datetime import datetime
from pydantic import BaseModel


class User(BaseModel):
    id: int
    name = 'John Doe'
    signup_ts: datetime = None
      
m = User.parse_raw('{"id": 123, "name": "James"}')
print(m)
# > id=123 signup_ts=None name='James'

此外,它能直接將ORM的對象輸入,轉(zhuǎn)為Pydantic的對象,比如從Sqlalchemy ORM:

上滑查看更多代碼

from typingimport List
from sqlalchemyimport Column, Integer, String
from sqlalchemy.dialects.postgresqlimport ARRAY
from sqlalchemy.ext.declarativeimport declarative_base
from pydanticimport BaseModel, constr

Base = declarative_base()


class CompanyOrm(Base):
__tablename__ ='companies'
id = Column(Integer, primary_key=True, nullable=False)
public_key = Column(String(20), index=True, nullable=False, unique=True)
name = Column(String(63), unique=True)
domains = Column(ARRAY(String(255)))


class CompanyModel(BaseModel):
id: int
public_key: constr(max_length=20)
name: constr(max_length=63)
domains: List[constr(max_length=255)]

class Config:
orm_mode =True


co_orm = CompanyOrm(
id=123,
public_key='foobar',
name='Testing',
domains=['example.com','foobar.com'],
)
print(co_orm)
# > < models_orm_mode.CompanyOrm object at 0x7f0bdac44850 >
co_model = CompanyModel.from_orm(co_orm)
print(co_model)
# > id=123 public_key='foobar' name='Testing' domains=['example.com',
# > 'foobar.com']

從Json文件導入:

from datetime import datetime
from pathlib import Path
from pydantic import BaseModel


class User(BaseModel):
    id: int
    name = 'John Doe'
    signup_ts: datetime = None
      
path = Path('data.json')
path.write_text('{"id": 123, "name": "James"}')
m = User.parse_file(path)
print(m)

從pickle導入:

import pickle
from datetime import datetime
from pydantic import BaseModel

pickle_data = pickle.dumps({
    'id': 123,
    'name': 'James',
    'signup_ts': datetime(2017, 7, 14)
})
m = User.parse_raw(
    pickle_data, content_type='application/pickle', allow_pickle=True
)
print(m)
# > id=123 signup_ts=datetime.datetime(2017, 7, 14, 0, 0) name='James'

3.自定義數(shù)據(jù)校驗

你還能給它增加 validator 裝飾器,增加你需要的校驗邏輯:

上滑查看更多代碼

from sklearn.metrics import confusion_matrix
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# 1.導入數(shù)據(jù)集
dataset = pd.read_csv('Social_Network_Ads.csv')
X = dataset.iloc[:, [1, 2, 3]].values
Y = dataset.iloc[:, 4].values

# 性別轉(zhuǎn)化為數(shù)字
labelencoder_X = LabelEncoder()
X[:, 0] = labelencoder_X.fit_transform(X[:, 0])

# 2.將數(shù)據(jù)集分成訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(
    X, Y, test_size=0.25, random_state=0)

# 3.特征縮放
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

# 4.訓練
classifier = LogisticRegression()
classifier.fit(X_train, y_train)

# 5.預測
y_pred = classifier.predict(X_test)

# 6.評估預測

# 生成混淆矩陣
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
print(cm)

上面,我們增加了三種自定義校驗邏輯:

1.name 必須帶有空格

2.password2 必須和 password1 相同

3.username 必須為字母

讓我們試試這三個校驗是否有效:

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里的數(shù)據(jù)完全沒有問題,通過校驗。

第二個UserModel里的數(shù)據(jù),由于name存在空格,password2和password1不一致,無法通過校驗。因此我們定義的自定義校驗器完全有效。

4.性能表現(xiàn)

這是最令我驚訝的部分,Pydantic 比 Django-rest-framework 的校驗器還快了12.3倍:

Package版本相對表現(xiàn)平均耗時
pydantic1.7.393.7μs
attrs + cattrs20.31.5x slower143.6μs
valideer0.4.21.9x slower175.9μs
marshmallow3.102.4x slower227.6μs
voluptuous0.122.7x slower257.5μs
trafaret2.1.03.2x slower296.7μs
schematics2.1.010.2x slower955.5μs
django-rest-framework3.1212.3x slower1148.4μs
cerberus1.3.225.9x slower2427.6μs
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 模塊
    +關注

    關注

    7

    文章

    2657

    瀏覽量

    47294
  • 數(shù)據(jù)

    關注

    8

    文章

    6819

    瀏覽量

    88743
  • 代碼
    +關注

    關注

    30

    文章

    4723

    瀏覽量

    68236
  • python
    +關注

    關注

    55

    文章

    4768

    瀏覽量

    84376
收藏 人收藏

    評論

    相關推薦

    實時嵌入式系統(tǒng)模型校驗技術

    模型校驗是最成功的需求驗證工具。模型校驗的基本原理如圖1所示。模型校驗工具的輸入是系統(tǒng)需求或設計(稱為模型)以及最終系統(tǒng)期望實現(xiàn)的特性(稱為
    發(fā)表于 11-01 18:14 ?817次閱讀
    實時嵌入式系統(tǒng)模型<b class='flag-5'>校驗</b>技術

    基于Atmega128單片機和CRC校驗碼實現(xiàn)無線傳輸數(shù)據(jù)時的差錯校驗

    隨著技術的不斷進步,各種數(shù)據(jù)通信的應用越來越廣泛。由于傳輸距離、現(xiàn)場狀況、干擾等諸多因素的影響,設備之間的通信數(shù)據(jù)常會發(fā)生一些無法預測的錯誤。為了降低錯誤所帶來的影響,一般在通信時采用數(shù)據(jù)校驗
    的頭像 發(fā)表于 05-05 17:36 ?3300次閱讀
    基于Atmega128單片機和CRC<b class='flag-5'>校驗</b>碼實現(xiàn)無線傳輸<b class='flag-5'>數(shù)據(jù)</b>時的差錯<b class='flag-5'>校驗</b>

    英飛凌強大的AURIX和工具鏈簡介

    英飛凌強大的AURIX,工具鏈簡介,謝謝北京西能提供工具簡介資料,希望對學習Tricore的童鞋有所指引。Aurix開發(fā)工具鏈20131219.pdf (1.03 MB )
    發(fā)表于 12-14 10:42

    校驗遇到數(shù)據(jù)校驗不到而導致出錯

    串口發(fā)送數(shù)據(jù)時,利用和校驗的方法對數(shù)據(jù)進行校驗,但是遇到數(shù)據(jù)校驗不到而導致出錯,請問這種情況該如
    發(fā)表于 04-14 23:04

    CRC校驗代碼自動生成工具

    CRC校驗代碼自動生成工具根據(jù)輸入條件自動產(chǎn)生各種CRC的VHDL或verilog源程序
    發(fā)表于 05-20 11:16 ?294次下載
    CRC<b class='flag-5'>校驗</b>代碼自動生成<b class='flag-5'>工具</b>

    基于Labview的串口通信數(shù)據(jù)校驗和的實現(xiàn)方法

    基于Labview的串口通信數(shù)據(jù)校驗和的實現(xiàn)方法
    發(fā)表于 01-09 17:58 ?172次下載
    基于Labview的串口通信<b class='flag-5'>數(shù)據(jù)</b><b class='flag-5'>校驗</b>和的實現(xiàn)方法

    校驗位的小工具

    電子發(fā)燒友網(wǎng)站提供《算校驗位的小工具.exe》資料免費下載
    發(fā)表于 07-25 16:06 ?2次下載

    文件校驗工具

    支持校驗文件的MD5SHA-256等值
    發(fā)表于 05-05 08:37 ?16次下載

    循環(huán)冗余校驗奇偶校驗累加和校驗等知識分享

    CRC校驗(循環(huán)冗余校驗)是數(shù)據(jù)通訊中最常采用的校驗方式。在嵌入式軟件開發(fā)中,經(jīng)常要用到CRC
    的頭像 發(fā)表于 11-08 09:31 ?8695次閱讀
    循環(huán)冗余<b class='flag-5'>校驗</b>奇偶<b class='flag-5'>校驗</b>累加和<b class='flag-5'>校驗</b>等知識分享

    奇偶校驗是什么

    校驗依據(jù):判斷傳輸?shù)囊唤M二進制數(shù)據(jù)中”1”的個數(shù)是奇數(shù)還是偶數(shù) 奇校驗:如果以二進制數(shù)據(jù)中1的個數(shù)是奇數(shù)為依據(jù),則是奇校驗
    發(fā)表于 07-31 17:35 ?4次下載
    奇偶<b class='flag-5'>校驗</b>是什么

    數(shù)據(jù)是如何使VPN成為強大工具

    隨著時間的推移,大數(shù)據(jù)已經(jīng)使VPN成為強大的隱私工具。而即使到現(xiàn)在,這種情況仍在持續(xù)。
    發(fā)表于 03-12 15:22 ?1232次閱讀

    單片機通信數(shù)據(jù)校驗

    單片機通信數(shù)據(jù)校驗
    發(fā)表于 11-23 17:36 ?33次下載
    單片機通信<b class='flag-5'>數(shù)據(jù)</b><b class='flag-5'>校驗</b>

    工控常用LRC XOR累加和CRC校驗工具校驗碼自動生成軟件多計算方式

    CRC校驗工具 校驗碼自動生成軟件支持十幾種CRC計算方式,包括MODBUS協(xié)議的CRC-16校驗,CRC4、CRC5、CRC6、CRC7、CRC8、CRC16等21種算法,見圖示。兩
    的頭像 發(fā)表于 11-25 14:27 ?3328次閱讀
    工控常用LRC XOR累加和CRC<b class='flag-5'>校驗</b><b class='flag-5'>工具</b><b class='flag-5'>校驗</b>碼自動生成軟件多計算方式

    什么是奇校驗和偶校驗?常見的奇偶校驗方式有哪些?

    什么是奇校驗和偶校驗?常見的奇偶校驗方式有哪些? 1. 奇偶校驗是指在數(shù)字通信中采用一種技術對傳輸?shù)?b class='flag-5'>數(shù)據(jù)進行
    的頭像 發(fā)表于 10-17 16:28 ?1w次閱讀

    奇偶校驗和crc校驗的區(qū)別 CRC校驗和奇偶校驗之間有什么關系?

    奇偶校驗和crc校驗的區(qū)別 CRC校驗和奇偶校驗之間有什么關系? 奇偶校驗和 CRC(Cyclic Redundancy Check)
    的頭像 發(fā)表于 10-17 16:28 ?3208次閱讀