Python通過Schema實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證方式
Schema是什么?
不管我們做什么應(yīng)用,只要和用戶輸入打交道,就有一個(gè)原則--永遠(yuǎn)不要相信用戶的輸入數(shù)據(jù)。意味著我們要對(duì)用戶輸入進(jìn)行嚴(yán)格的驗(yàn)證,web開發(fā)時(shí)一般輸入數(shù)據(jù)都以JSON形式發(fā)送到后端API,API要對(duì)輸入數(shù)據(jù)做驗(yàn)證。一般我都是加很多判斷,各種if,導(dǎo)致代碼很丑陋,能不能有一種方式比較優(yōu)雅的驗(yàn)證用戶數(shù)據(jù)呢?Schema就派上用場(chǎng)了。
Schema非常簡(jiǎn)單,也就幾百行的代碼,最核心的類就一個(gè):Schema。
1. 給Schema類傳入類型(int、str、float等)
例如:
from schema import Schema
Schema(int).validate(10)
10
Schema(int).validate('10')
SchemaUnexpectedTypeError: '10' should be instance of 'int'
可見Schema會(huì)去驗(yàn)證validate方法傳入的對(duì)象是不是所指定的類型,是則返回傳入的數(shù)據(jù),否則拋出一個(gè)SchemaError的異常(SchemaUnexpectedTypeError是SchemaError的子類)。
2. 給Schema類傳入可調(diào)用的對(duì)象(函數(shù)、帶__call__的類等)
例如:
Schema(lambda x: 0<x<10).validate(5)
5
Schema(lambda x: 0<x<10).validate(57)
SchemaError: <lambda>(57) should evaluate to True
可見Schema會(huì)把validate方法傳入的值傳入到對(duì)應(yīng)的函數(shù)里面作為參數(shù),如果函數(shù)返回值為True則返回輸入數(shù)據(jù),否則拋出異常。
3. 給Schema類傳入帶有validate方法的對(duì)象
Schema也內(nèi)置了一些類(Use、And、Or等等),這些類的實(shí)例都帶有validate方法,亦可作為Schema的參數(shù)傳入,例如:
from schema import Schema, And
# And代表兩個(gè)條件必須同時(shí)滿足
Schema(And(str, lambda s: len(s) > 2)).validate('abcd')
'abcd'
4. 給Schema類傳入容器對(duì)象(list、tuple、set等)
例如:
Schema([int, float]).validate([1, 2, 3, 4.0])
[1, 2, 3, 4.0]
相當(dāng)于,對(duì)于[1, 2, 3, 4.0]當(dāng)中的任何一個(gè)元素,必須是int或者float才行(注意是or的關(guān)系)
5. 給Schema傳入一個(gè)字典對(duì)象(大部分使用Schema的場(chǎng)景都是傳入字典對(duì)象,這個(gè)很重要)
Schema({'name': str, 'age': int}).validate({'name': 'foobar', 'age': 18})
{'age': 18, 'name': 'foobar'}
Schema({'name': str, 'age': int}).validate({'name': 'foobar'})
SchemaMissingKeyError: Missing keys: 'age'
首先,明確兩個(gè)概念,Schema類傳入的字典,稱之為模式字典,valdiate方法傳入的字典稱之為數(shù)據(jù)字典。
首先,Schema會(huì)判斷, 模式字典和數(shù)據(jù)字典的key是否完全一樣,不一樣的話直接拋出異常。如果一樣,就去拿數(shù)據(jù)字典的value去驗(yàn)證模式字典相應(yīng)的value,如果數(shù)據(jù)字典的全部value都可以驗(yàn)證通過的話才返回?cái)?shù)據(jù),否則拋出異常,是不是感覺這種驗(yàn)證頓時(shí)感覺清爽了呢?
6. faqs
Schema傳入字典很好用,但是我有的數(shù)據(jù)是可選的,也就是說有的key可以不提供怎么辦?
from schema import Optional, Schema
Schema({'name': str, Optional('age'): int}).validate({'name': 'foobar'})
{'name': 'foobar'}
Schema({'name': str, Optional('age', default=18): int}).validate({'name': 'foobar'})
{'age': 18, 'name': 'foobar'}
我想讓Schema只驗(yàn)證傳入字典中的一部分?jǐn)?shù)據(jù),可以有多余的key但是不要抱錯(cuò),怎么做?
Schema({'name': str, 'age': int}, ignore_extra_keys=True).validate({'name': 'foobar', 'age': 100, 'sex': 'male'})
{'age': 100, 'name': 'foobar'}
Schema拋出的異常信息不是很友好,我想自定義錯(cuò)誤信息,怎么辦?
Schema自帶的類(Use、And、Or、Regex、Schema等)都有一個(gè)參數(shù)error,可以自定義錯(cuò)誤信息
Schema({'name': str, 'age': Use(int, error='年齡必須是整數(shù)')}).validate({'name': 'foobar', 'age': 'abc'})
SchemaError: 年齡必須是整數(shù)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Django多數(shù)據(jù)庫(kù)的實(shí)現(xiàn)過程詳解
這篇文章主要介紹了Django多數(shù)據(jù)庫(kù)的實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08關(guān)于Tensorflow中的tf.train.batch函數(shù)的使用
本篇文章主要介紹了關(guān)于Tensorflow中的tf.train.batch函數(shù)的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04詳解在Python程序中解析并修改XML內(nèi)容的方法
這篇文章主要介紹了在Python程序中解析并修改XML內(nèi)容的方法,依賴于解析成樹狀結(jié)構(gòu)后的節(jié)點(diǎn)進(jìn)行修改,需要的朋友可以參考下2015-11-11對(duì)python append 與淺拷貝的實(shí)例講解
今天小編就為大家分享一篇對(duì)python append 與淺拷貝的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-05-05pycharm社區(qū)版安裝node.js插件運(yùn)行js代碼方法
PyCharm可以說是當(dāng)今最流行的一款Python IDE了,下面這篇文章主要給大家介紹了關(guān)于pycharm社區(qū)版安裝node.js插件運(yùn)行js代碼的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10

Python多線程實(shí)現(xiàn)支付模擬請(qǐng)求過程解析

python實(shí)現(xiàn)根據(jù)文件格式分類