Python 中的Schema數(shù)據(jù)結(jié)構(gòu)及類型校驗(yàn)詳解
使用
schema
庫來執(zhí)行數(shù)據(jù)結(jié)構(gòu)的校驗(yàn)。schema
是一個(gè)簡單而強(qiáng)大的庫,用于定義和驗(yàn)證 Python 數(shù)據(jù)結(jié)構(gòu)的約束
And
And
代表必選,數(shù)據(jù)結(jié)構(gòu)里必須包含這個(gè) schema,如下方聲明了name
,則代表這個(gè)name
必須存在與字典中
from schema import Schema, And, SchemaError user_schema = Schema([ { "name": And(str) } ]) user_data_1 = [{ "name": "jruing", }] user_data_2 = [{ "name": 666, }] try: user_result_1 = user_schema.validate(user_data_1) print(f"數(shù)據(jù)校驗(yàn)user_result_1:{user_result_1}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_1:{e}") try: user_result_2 = user_schema.validate(user_data_2) print(f"數(shù)據(jù)校驗(yàn)user_result_2:{user_result_2}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_2:{e}") ==========調(diào)用結(jié)果========== 數(shù)據(jù)校驗(yàn)user_result_1:[{'name': 'jruing'}] 數(shù)據(jù)校驗(yàn)異常user_result_2:Or({'name': And(<class 'str'>)}) did not validate {'name': 666} Key 'name' error: 666 should be instance of 'str'
Or
Or
代表值的類型必須為某兩個(gè)類型,比如int
或float
,tuple
或list
from schema import Schema, And, SchemaError, Or user_schema = Schema([ { "name": And(str), "money": Or(int,float) } ]) user_data_1 = [{ "name": "jruing", "money": 1000, }] user_data_2 = [{ "name": "jruing", "money": 1000.1, }] user_data_3 = [{ "name": "jruing", "money": "1000.1", }] try: user_result_1 = user_schema.validate(user_data_1) print(f"數(shù)據(jù)校驗(yàn)user_result_1:{user_result_1}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_1:{e}") try: user_result_2 = user_schema.validate(user_data_2) print(f"數(shù)據(jù)校驗(yàn)user_result_2:{user_result_2}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_2:{e}") try: user_result_3 = user_schema.validate(user_data_3) print(f"數(shù)據(jù)校驗(yàn)user_result_3:{user_result_3}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_3:{e}") ==========調(diào)用結(jié)果========== 數(shù)據(jù)校驗(yàn)user_result_1:[{'name': 'jruing', 'money': 1000, 'addr': '中國', 'country': '中國', 'email': '123456@qq.com'}] 數(shù)據(jù)校驗(yàn)異常user_result_2:Or({'name': And(<class 'str'>), 'money': Or(<class 'int'>, <class 'float'>), Optional('addr'): And(<class 'str'>), Optional('email'): And(<class 'str'>, Regex('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$', flags=re.IGNORECASE)), 'country': Const('中國')}) did not validate {'name': 'jruing', 'money': 1000.1, 'addr': '1111', 'country': '山西', 'email': '123456'} Key 'country' error: '中國' does not match '山西'
Const
Const
代表值必須為指定的某個(gè)常量,比如下面的country
必須為中國
import re from schema import Schema, And, SchemaError, Or, Optional, Regex, Const user_schema = Schema([ { "name": And(str), "money": Or(int, float), Optional("addr"): And(str), Optional("email"): And(str, Regex(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$', flags=re.I)), "country": Const("中國") } ]) user_data_1 = [{ "name": "jruing", "money": 1000, "addr": "中國", "country": "中國", "email": "123456@qq.com" }] user_data_2 = [{ "name": "jruing", "money": 1000.1, "addr": "1111", "country": "山西", "email": "123456" }] try: user_result_1 = user_schema.validate(user_data_1) print(f"數(shù)據(jù)校驗(yàn)user_result_1:{user_result_1}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_1:{e}") try: user_result_2 = user_schema.validate(user_data_2) print(f"數(shù)據(jù)校驗(yàn)user_result_2:{user_result_2}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_2:{e}") ==========調(diào)用結(jié)果========== 數(shù)據(jù)校驗(yàn)user_result_1:[{'name': 'jruing', 'money': 1000, 'addr': '中國', 'country': '中國', 'email': '123456@qq.com'}] 數(shù)據(jù)校驗(yàn)異常user_result_2:Or({'name': And(<class 'str'>), 'money': Or(<class 'int'>, <class 'float'>), Optional('addr'): And(<class 'str'>), Optional('email'): And(<class 'str'>, Regex('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$', flags=re.IGNORECASE)), 'country': Const('中國')}) did not validate {'name': 'jruing', 'money': 1000.1, 'addr': '1111', 'country': '山西', 'email': '123456'} Key 'country' error: '中國' does not match '山西'
Optional
Optional
代表這個(gè)key或者元素為非必選,可有可無
from schema import Schema, And, SchemaError, Or, Optional user_schema = Schema([ { "name": And(str), "money": Or(int, float), Optional("addr"): And(str) } ]) user_data_1 = [{ "name": "jruing", "money": 1000, "addr": "中國" }] user_data_2 = [{ "name": "jruing", "money": 1000.1, }] try: user_result_1 = user_schema.validate(user_data_1) print(f"數(shù)據(jù)校驗(yàn)user_result_1:{user_result_1}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_1:{e}") try: user_result_2 = user_schema.validate(user_data_2) print(f"數(shù)據(jù)校驗(yàn)user_result_2:{user_result_2}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_2:{e}") ==========調(diào)用結(jié)果========== 數(shù)據(jù)校驗(yàn)user_result_1:[{'name': 'jruing', 'money': 1000, 'addr': '中國'}] 數(shù)據(jù)校驗(yàn)user_result_2:[{'name': 'jruing', 'money': 1000.1}]
Use
Use
函數(shù)允許你在驗(yàn)證前對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)換。這對(duì)于在驗(yàn)證之前對(duì)數(shù)據(jù)進(jìn)行清理、格式化或其他操作非常有用。
import re from schema import Schema, And, SchemaError, Or, Optional, Regex, Const, Use user_schema = Schema([ { "name": And(str), "money": Or(int, float), "age": Use(int), Optional("addr"): And(str), Optional("email"): And(str, Regex(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$', flags=re.I)), Optional("country"): Const("中國") } ]) user_data_1 = [{ "name": "jruing", "money": 1000, "age": 11, "addr": "中國", "country": "中國", "email": "123456@qq.com" }] user_data_2 = [{ "name": "jruing", "money": 1000.1, "age": "18", "addr": "1111", "email": "123456@qq.com" }] user_data_3 = [{ "name": "jruing", "money": 1000.1, "age": "fff", "addr": "1111", "email": "123456@qq.com" }] try: user_result_1 = user_schema.validate(user_data_1) print(f"數(shù)據(jù)校驗(yàn)user_result_1:{user_result_1}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_1:{e}") try: user_result_2 = user_schema.validate(user_data_2) print(f"數(shù)據(jù)校驗(yàn)user_result_2:{user_result_2}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_2:{e}") try: user_result_3 = user_schema.validate(user_data_3) print(f"數(shù)據(jù)校驗(yàn)user_result_3:{user_result_3}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_3:{e}") ==========調(diào)用結(jié)果========== 數(shù)據(jù)校驗(yàn)user_result_1:[{'name': 'jruing', 'money': 1000, 'age': 11, 'addr': '中國', 'country': '中國', 'email': '123456@qq.com'}] 數(shù)據(jù)校驗(yàn)user_result_2:[{'name': 'jruing', 'money': 1000.1, 'age': 18, 'addr': '1111', 'email': '123456@qq.com'}] 數(shù)據(jù)校驗(yàn)異常user_result_3:Or({'name': And(<class 'str'>), 'money': Or(<class 'int'>, <class 'float'>), 'age': Use(<class 'int'>), Optional('addr'): And(<class 'str'>), Optional('email'): And(<class 'str'>, Regex('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$', flags=re.IGNORECASE)), Optional('country'): Const('中國')}) did not validate {'name': 'jruing', 'money': 1000.1, 'age': 'fff', 'addr': '1111', 'email': '123456@qq.com'} Key 'age' error: int('fff') raised ValueError("invalid literal for int() with base 10: 'fff'")
Regex
通過正則表達(dá)式,對(duì)值進(jìn)行匹配校驗(yàn),常用的就是郵箱,手機(jī)號(hào)等場景
import re from schema import Schema, And, SchemaError, Or, Optional, Regex user_schema = Schema([ { "name": And(str), "money": Or(int, float), Optional("addr"): And(str), Optional("email"): And(str, Regex(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$', flags=re.I)) } ]) user_data_1 = [{ "name": "jruing", "money": 1000, "addr": "中國", "email": "123456@qq.com" }] user_data_2 = [{ "name": "jruing", "money": 1000.1, "addr": "1111", "email": "123456" }] try: user_result_1 = user_schema.validate(user_data_1) print(f"數(shù)據(jù)校驗(yàn)user_result_1:{user_result_1}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_1:{e}") try: user_result_2 = user_schema.validate(user_data_2) print(f"數(shù)據(jù)校驗(yàn)user_result_2:{user_result_2}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_2:{e}") ==========調(diào)用結(jié)果========== 數(shù)據(jù)校驗(yàn)user_result_1:[{'name': 'jruing', 'money': 1000, 'addr': '中國', 'email': '123456@qq.com'}] 數(shù)據(jù)校驗(yàn)異常user_result_2:Or({'name': And(<class 'str'>), 'money': Or(<class 'int'>, <class 'float'>), Optional('addr'): And(<class 'str'>), Optional('email'): And(<class 'str'>, Regex('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$', flags=re.IGNORECASE))}) did not validate {'name': 'jruing', 'money': 1000.1, 'addr': '1111', 'email': '123456'} Key 'email' error: Regex('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$', flags=re.IGNORECASE) does not match '123456'
Forbidden
Forbidder
允許你定義一些不被允許的值,如果數(shù)據(jù)中包含這些值,驗(yàn)證將失敗,下面的例子表示密碼password
字段的值不允許設(shè)置為123456
import re from schema import Schema, And, SchemaError, Or, Optional, Regex, Const, Use, Forbidden user_schema = Schema([ { "name": And(str), "money": Or(int, float), "age": Use(int), Optional("addr"): And(str), Optional("email"): And(str, Regex(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$', flags=re.I)), Optional("country"): Const("中國"), "password": And(str, Forbidden("123456")) } ]) user_data_1 = [{ "name": "jruing", "money": 1000, "age": 11, "addr": "中國", "country": "中國", "email": "123456@qq.com", "password": "123456" }] user_data_2 = [{ "name": "jruing", "money": 1000.1, "age": "18", "addr": "1111", "email": "123456@qq.com", "password": "1234561" }] try: user_result_1 = user_schema.validate(user_data_1) print(f"數(shù)據(jù)校驗(yàn)user_result_1:{user_result_1}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_1:{e}") try: user_result_2 = user_schema.validate(user_data_2) print(f"數(shù)據(jù)校驗(yàn)user_result_2:{user_result_2}") except SchemaError as e: print(f"數(shù)據(jù)校驗(yàn)異常user_result_2:{e}") ==========調(diào)用結(jié)果========== 數(shù)據(jù)校驗(yàn)user_result_1:[{'name': 'jruing', 'money': 1000, 'age': 11, 'addr': '中國', 'country': '中國', 'email': '123456@qq.com', 'password': '123456'}] 數(shù)據(jù)校驗(yàn)異常user_result_2:Or({'name': And(<class 'str'>), 'money': Or(<class 'int'>, <class 'float'>), 'age': Use(<class 'int'>), Optional('addr'): And(<class 'str'>), Optional('email'): And(<class 'str'>, Regex('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$', flags=re.IGNORECASE)), Optional('country'): Const('中國'), 'password': And(<class 'str'>, Forbidden('123456'))}) did not validate {'name': 'jruing', 'money': 1000.1, 'age': '18', 'addr': '1111', 'email': '123456@qq.com', 'password': '1234561'} Key 'password' error: '123456' does not match '1234561'
到此這篇關(guān)于Python 中的Schema數(shù)據(jù)結(jié)構(gòu)及類型校驗(yàn)的文章就介紹到這了,更多相關(guān)Python Schema數(shù)據(jù)結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python將列表中的元素轉(zhuǎn)化為數(shù)字并排序的示例
今天小編就為大家分享一篇Python將列表中的元素轉(zhuǎn)化為數(shù)字并排序的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12在python下使用tensorflow判斷是否存在文件夾的實(shí)例
今天小編就為大家分享一篇在python下使用tensorflow判斷是否存在文件夾的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-06-06利用Python實(shí)現(xiàn)自動(dòng)化監(jiān)控文件夾完成服務(wù)部署
本篇文章將為大家詳細(xì)介紹如何利用Python語言實(shí)現(xiàn)監(jiān)控文件夾,以此輔助完成服務(wù)的部署動(dòng)作,文中的示例代碼講解詳細(xì),感興趣的可以嘗試一下2022-07-07PyQt5 實(shí)現(xiàn)給無邊框widget窗口添加背景圖片
這篇文章主要介紹了PyQt5 實(shí)現(xiàn)給無邊框widget窗口添加背景圖片的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-03-03