Python通过Schema实现数据验证方式


Posted in Python onNovember 12, 2020

Schema是什么?

不管我们做什么应用,只要和用户输入打交道,就有一个原则--永远不要相信用户的输入数据。意味着我们要对用户输入进行严格的验证,web开发时一般输入数据都以JSON形式发送到后端API,API要对输入数据做验证。一般我都是加很多判断,各种if,导致代码很丑陋,能不能有一种方式比较优雅的验证用户数据呢?Schema就派上用场了。

Schema非常简单,也就几百行的代码,最核心的类就一个: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会去验证validate方法传入的对象是不是所指定的类型,是则返回传入的数据,否则抛出一个SchemaError的异常(SchemaUnexpectedTypeError是SchemaError的子类)。

2. 给Schema类传入可调用的对象(函数、带__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会把validate方法传入的值传入到对应的函数里面作为参数,如果函数返回值为True则返回输入数据,否则抛出异常。

3. 给Schema类传入带有validate方法的对象

Schema也内置了一些类(Use、And、Or等等),这些类的实例都带有validate方法,亦可作为Schema的参数传入,例如:

from schema import Schema, And

# And代表两个条件必须同时满足
Schema(And(str, lambda s: len(s) > 2)).validate('abcd')
'abcd'

4. 给Schema类传入容器对象(list、tuple、set等)

例如:

Schema([int, float]).validate([1, 2, 3, 4.0])
[1, 2, 3, 4.0]

相当于,对于[1, 2, 3, 4.0]当中的任何一个元素,必须是int或者float才行(注意是or的关系)

5. 给Schema传入一个字典对象(大部分使用Schema的场景都是传入字典对象,这个很重要)

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'

首先,明确两个概念,Schema类传入的字典,称之为模式字典,valdiate方法传入的字典称之为数据字典。

首先,Schema会判断, 模式字典和数据字典的key是否完全一样,不一样的话直接抛出异常。如果一样,就去拿数据字典的value去验证模式字典相应的value,如果数据字典的全部value都可以验证通过的话才返回数据,否则抛出异常,是不是感觉这种验证顿时感觉清爽了呢?

6. faqs

Schema传入字典很好用,但是我有的数据是可选的,也就是说有的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只验证传入字典中的一部分数据,可以有多余的key但是不要抱错,怎么做?

Schema({'name': str, 'age': int}, ignore_extra_keys=True).validate({'name': 'foobar', 'age': 100, 'sex': 'male'})
{'age': 100, 'name': 'foobar'}

Schema抛出的异常信息不是很友好,我想自定义错误信息,怎么办?

Schema自带的类(Use、And、Or、Regex、Schema等)都有一个参数error,可以自定义错误信息

Schema({'name': str, 'age': Use(int, error='年龄必须是整数')}).validate({'name': 'foobar', 'age': 'abc'})

SchemaError: 年龄必须是整数

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python处理文本文件并生成指定格式的文件
Jul 31 Python
python中实现迭代器(iterator)的方法示例
Jan 19 Python
详解Python pygame安装过程笔记
Jun 05 Python
python 检查是否为中文字符串的方法
Dec 28 Python
Python登录系统界面实现详解
Jun 25 Python
使用Python实现图像标记点的坐标输出功能
Aug 14 Python
pytorch之Resize()函数具体使用详解
Feb 27 Python
Django-migrate报错问题解决方案
Apr 21 Python
python 异步async库的使用说明
May 04 Python
python3 通过 pybind11 使用Eigen加速代码的步骤详解
Dec 07 Python
Python基于mediainfo批量重命名图片文件
Dec 29 Python
Python爬虫网络请求之代理服务器和动态Cookies
Apr 12 Python
Django用户认证系统如何实现自定义
Nov 12 #Python
Django自带用户认证系统使用方法解析
Nov 12 #Python
Django多数据库联用实现方法解析
Nov 12 #Python
Django数据库迁移常见使用方法
Nov 12 #Python
python爬虫中PhantomJS加载页面的实例方法
Nov 12 #Python
python调用win32接口进行截图的示例
Nov 11 #Python
python 下载m3u8视频的示例代码
Nov 11 #Python
You might like
解析PHP的session过期设置
2013/06/29 PHP
模板引擎smarty工作原理以及使用示例
2014/05/25 PHP
关于jquery动态增减控件的一些想法和小插件
2010/08/01 Javascript
理解Javascript_02_理解undefined和null
2010/10/11 Javascript
jQuery文字轮播特效
2017/02/12 Javascript
discuz表情的JS提取方法分析
2017/03/22 Javascript
JS作用域链详解
2017/06/26 Javascript
JS脚本实现网页自动秒杀点击
2018/01/11 Javascript
vue router 配置路由的方法
2018/07/26 Javascript
fastadmin中调用js的方法
2019/05/14 Javascript
mpvue实现微信小程序快递单号查询代码
2020/04/03 Javascript
[03:55]显微镜下的DOTA2特别篇——430灰烬之灵神级操作
2014/06/24 DOTA
跟老齐学Python之折腾一下目录
2014/10/24 Python
Python字符串逐字符或逐词反转方法
2015/05/21 Python
浅谈python抛出异常、自定义异常, 传递异常
2016/06/20 Python
浅析python中的分片与截断序列
2016/08/09 Python
Fabric 应用案例
2016/08/28 Python
python 实现在tkinter中动态显示label图片的方法
2019/06/13 Python
pyqt5对用qt designer设计的窗体实现弹出子窗口的示例
2019/06/19 Python
django框架基于queryset和双下划线的跨表查询操作详解
2019/12/11 Python
python实现简单俄罗斯方块
2020/03/13 Python
Python爬虫爬取电影票房数据及图表展示操作示例
2020/03/27 Python
python中scrapy处理项目数据的实例分析
2020/11/22 Python
scrapy实践之翻页爬取的实现
2021/01/05 Python
HTML5的结构和语义(1):前言
2008/10/17 HTML / CSS
英国时尚运动品牌的合集:The Sports Edit
2017/12/20 全球购物
自荐信封面
2013/12/04 职场文书
中式面点餐厅创业计划书
2014/01/29 职场文书
学雷锋演讲稿
2014/03/04 职场文书
机关党员进社区活动总结
2014/07/05 职场文书
先进集体事迹材料范文
2014/12/25 职场文书
医德医风自我评价2015
2015/03/03 职场文书
毕业论文致谢部分怎么写
2015/05/14 职场文书
Springboot如何同时装配两个相同类型数据库
2021/11/17 Java/Android
Python中如何处理常见报错
2022/01/18 Python
Windows server 2012 R2 安装IIS服务器
2022/04/29 Servers