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制作检测Linux运行信息的工具的教程
Apr 01 Python
python 正确保留多位小数的实例
Jul 16 Python
python实现ID3决策树算法
Aug 29 Python
django 外键model的互相读取方法
Dec 15 Python
基于Python的Post请求数据爬取的方法详解
Jun 14 Python
Flask配置Cors跨域的实现
Jul 12 Python
Python简单实现区域生长方式
Jan 16 Python
django使用JWT保存用户登录信息
Apr 22 Python
Django crontab定时任务模块操作方法解析
Sep 10 Python
Python命令行参数定义及需要注意的地方
Nov 30 Python
Python中的min及返回最小值索引的操作
May 10 Python
python处理json数据文件
Apr 11 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
基于python发送邮件的乱码问题的解决办法
2013/04/25 PHP
Php output buffering缓存及程序缓存深入解析
2013/07/15 PHP
判断JavaScript对象是否可用的最正确方法分析
2008/10/03 Javascript
JavaScript各类型的关系图解
2015/10/16 Javascript
javascript实现C语言经典程序题
2015/11/29 Javascript
JS深度拷贝Object Array实例分析
2016/03/31 Javascript
Bootstrap选项卡与Masonry插件的完美结合
2016/07/06 Javascript
js正则表达式注册页面表单验证
2016/10/11 Javascript
JavaScript 继承详解(五)
2016/10/11 Javascript
Canvas实现放射线动画效果
2017/02/15 Javascript
javaScript 连接打印机,打印小票的实例
2017/12/29 Javascript
vue axios登录请求拦截器
2018/04/02 Javascript
Vue中Axios从远程/后台读取数据
2019/01/21 Javascript
[51:26]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#3Secret VS OG第二局
2016/03/03 DOTA
[55:54]FNATIC vs EG 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
python使用fileinput模块实现逐行读取文件的方法
2015/04/29 Python
Python实现简单拆分PDF文件的方法
2015/07/30 Python
使用Python3制作TCP端口扫描器
2017/04/17 Python
Python编程实现双击更新所有已安装python模块的方法
2017/06/05 Python
Python标准库之itertools库的使用方法
2017/09/07 Python
Django处理文件上传File Uploads的实例
2018/05/28 Python
python 2.7.13 安装配置方法图文教程
2018/09/18 Python
对python 树状嵌套结构的实现思路详解
2019/08/09 Python
windows下python安装pip方法详解
2020/02/10 Python
Python flask框架实现浏览器点击自定义跳转页面
2020/06/04 Python
老生常谈CSS中的长度单位
2016/06/27 HTML / CSS
JD Sports马来西亚:英国领先的运动鞋和运动服饰零售商
2018/03/13 全球购物
中东奢侈品购物网站:Ounass
2020/09/02 全球购物
一道SQL面试题
2012/12/31 面试题
先进事迹报告会感言
2014/01/24 职场文书
小学优秀班集体申报材料
2014/05/25 职场文书
海洋科学专业求职信
2014/08/10 职场文书
2014新生大学四年计划书
2014/09/21 职场文书
教师学习八项规定六项禁令思想汇报
2014/09/27 职场文书
导游词之峨眉乐山/兵马俑/北京故宫御花园
2019/09/03 职场文书
InterProcessMutex实现zookeeper分布式锁原理
2022/03/21 Java/Android