Python 中的Schema数据结构及类型校验详解

 更新时间:2023年11月21日 09:26:37   作者:jruing  
schema 是一个简单而强大的库,用于定义和验证 Python 数据结构的约束,使用 schema 库来执行数据结构的校验,本文给大家介绍Python 中的Schema数据结构及类型校验,感兴趣的朋友一起看看吧

使用 schema 库来执行数据结构的校验。schema 是一个简单而强大的库,用于定义和验证 Python 数据结构的约束

And

And 代表必选,数据结构里必须包含这个 schema,如下方声明了 name ,则代表这个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"数据校验user_result_1:{user_result_1}")
except SchemaError as e:
    print(f"数据校验异常user_result_1:{e}")
try:
    user_result_2 = user_schema.validate(user_data_2)
    print(f"数据校验user_result_2:{user_result_2}")
except SchemaError as e:
    print(f"数据校验异常user_result_2:{e}")
==========调用结果==========
数据校验user_result_1:[{'name': 'jruing'}]
数据校验异常user_result_2:Or({'name': And(<class 'str'>)}) did not validate {'name': 666}
Key 'name' error:
666 should be instance of 'str'

Or

Or 代表值的类型必须为某两个类型,比如int 或 floattuplelist

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"数据校验user_result_1:{user_result_1}")
except SchemaError as e:
    print(f"数据校验异常user_result_1:{e}")
try:
    user_result_2 = user_schema.validate(user_data_2)
    print(f"数据校验user_result_2:{user_result_2}")
except SchemaError as e:
    print(f"数据校验异常user_result_2:{e}")
try:
    user_result_3 = user_schema.validate(user_data_3)
    print(f"数据校验user_result_3:{user_result_3}")
except SchemaError as e:
    print(f"数据校验异常user_result_3:{e}")
==========调用结果==========
数据校验user_result_1:[{'name': 'jruing', 'money': 1000, 'addr': '中国', 'country': '中国', 'email': '123456@qq.com'}]
数据校验异常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 代表值必须为指定的某个常量,比如下面的 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"数据校验user_result_1:{user_result_1}")
except SchemaError as e:
    print(f"数据校验异常user_result_1:{e}")
try:
    user_result_2 = user_schema.validate(user_data_2)
    print(f"数据校验user_result_2:{user_result_2}")
except SchemaError as e:
    print(f"数据校验异常user_result_2:{e}")
==========调用结果==========
数据校验user_result_1:[{'name': 'jruing', 'money': 1000, 'addr': '中国', 'country': '中国', 'email': '123456@qq.com'}]
数据校验异常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 代表这个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"数据校验user_result_1:{user_result_1}")
except SchemaError as e:
    print(f"数据校验异常user_result_1:{e}")
try:
    user_result_2 = user_schema.validate(user_data_2)
    print(f"数据校验user_result_2:{user_result_2}")
except SchemaError as e:
    print(f"数据校验异常user_result_2:{e}")
==========调用结果==========
数据校验user_result_1:[{'name': 'jruing', 'money': 1000, 'addr': '中国'}]
数据校验user_result_2:[{'name': 'jruing', 'money': 1000.1}]

Use

Use 函数允许你在验证前对数据进行转换。这对于在验证之前对数据进行清理、格式化或其他操作非常有用。

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"数据校验user_result_1:{user_result_1}")
except SchemaError as e:
    print(f"数据校验异常user_result_1:{e}")
try:
    user_result_2 = user_schema.validate(user_data_2)
    print(f"数据校验user_result_2:{user_result_2}")
except SchemaError as e:
    print(f"数据校验异常user_result_2:{e}")
try:
    user_result_3 = user_schema.validate(user_data_3)
    print(f"数据校验user_result_3:{user_result_3}")
except SchemaError as e:
    print(f"数据校验异常user_result_3:{e}")
==========调用结果==========
数据校验user_result_1:[{'name': 'jruing', 'money': 1000, 'age': 11, 'addr': '中国', 'country': '中国', 'email': '123456@qq.com'}]
数据校验user_result_2:[{'name': 'jruing', 'money': 1000.1, 'age': 18, 'addr': '1111', 'email': '123456@qq.com'}]
数据校验异常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

通过正则表达式,对值进行匹配校验,常用的就是邮箱,手机号等场景

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"数据校验user_result_1:{user_result_1}")
except SchemaError as e:
    print(f"数据校验异常user_result_1:{e}")
try:
    user_result_2 = user_schema.validate(user_data_2)
    print(f"数据校验user_result_2:{user_result_2}")
except SchemaError as e:
    print(f"数据校验异常user_result_2:{e}")
==========调用结果==========
数据校验user_result_1:[{'name': 'jruing', 'money': 1000, 'addr': '中国', 'email': '123456@qq.com'}]
数据校验异常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 允许你定义一些不被允许的值,如果数据中包含这些值,验证将失败,下面的例子表示密码 password字段的值不允许设置为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"数据校验user_result_1:{user_result_1}")
except SchemaError as e:
    print(f"数据校验异常user_result_1:{e}")
try:
    user_result_2 = user_schema.validate(user_data_2)
    print(f"数据校验user_result_2:{user_result_2}")
except SchemaError as e:
    print(f"数据校验异常user_result_2:{e}")
==========调用结果==========    
数据校验user_result_1:[{'name': 'jruing', 'money': 1000, 'age': 11, 'addr': '中国', 'country': '中国', 'email': '123456@qq.com', 'password': '123456'}]
数据校验异常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'

到此这篇关于Python 中的Schema数据结构及类型校验的文章就介绍到这了,更多相关Python Schema数据结构内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python编码问题汇总

    python编码问题汇总

    这篇文章主要给大家分享的是python编码问题汇总,字符编码简单介绍和发展史及使用方法的一些介绍,文章内容详细,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-03-03
  • Python将列表中的元素转化为数字并排序的示例

    Python将列表中的元素转化为数字并排序的示例

    今天小编就为大家分享一篇Python将列表中的元素转化为数字并排序的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • 在python下使用tensorflow判断是否存在文件夹的实例

    在python下使用tensorflow判断是否存在文件夹的实例

    今天小编就为大家分享一篇在python下使用tensorflow判断是否存在文件夹的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06
  • python实现ftp文件传输功能

    python实现ftp文件传输功能

    这篇文章主要为大家详细介绍了python实现ftp文件传输功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • python中重启for循环,使其重新开始遍历

    python中重启for循环,使其重新开始遍历

    这篇文章主要介绍了python中重启for循环,使其重新开始遍历方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Python抓取网页图片难点分析

    Python抓取网页图片难点分析

    没想到python是如此强大,令人着迷,以前看见图片总是一张一张复制粘贴,现在好了,学会python就可以用程序将一张张图片,保存下来。今天网上冲浪看到很多美图,可是图片有点多,不想一张一张地复制粘贴,怎么办呢?办法总是有的,即便没有我们也可以创造一个办法
    2023-01-01
  • Python脚本Selenium及页面Web元素定位详解

    Python脚本Selenium及页面Web元素定位详解

    这篇文章主要为大家介绍了Python脚本中如何使用Selenium定位页面Web元素的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-10-10
  • python魔法方法之__setattr__()

    python魔法方法之__setattr__()

    这篇文章主要介绍了python魔法方法之__setattr__(),python提供了诸多的魔法方法,其中__setattr__()方法主要用于类实例进行属性赋值,接下来请和小编一起进入文章来了解更多相关内容吧
    2022-03-03
  • 利用Python实现自动化监控文件夹完成服务部署

    利用Python实现自动化监控文件夹完成服务部署

    本篇文章将为大家详细介绍如何利用Python语言实现监控文件夹,以此辅助完成服务的部署动作,文中的示例代码讲解详细,感兴趣的可以尝试一下
    2022-07-07
  • PyQt5 实现给无边框widget窗口添加背景图片

    PyQt5 实现给无边框widget窗口添加背景图片

    这篇文章主要介绍了PyQt5 实现给无边框widget窗口添加背景图片的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03

最新评论