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 相关文章推荐
Pyhton中防止SQL注入的方法
Feb 05 Python
python实现数值积分的Simpson方法实例分析
Jun 05 Python
Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法
Aug 16 Python
python对DICOM图像的读取方法详解
Jul 17 Python
Python探索之爬取电商售卖信息代码示例
Oct 27 Python
python实现随机梯度下降(SGD)
Mar 24 Python
python读取文本中的坐标方法
Oct 14 Python
PyCharm设置护眼背景色的方法
Oct 29 Python
django Admin文档生成器使用详解
Jul 22 Python
python字符串分割及字符串的一些常规方法
Jul 24 Python
Jmeter HTTPS接口测试证书导入过程图解
Jul 22 Python
python statsmodel的使用
Dec 21 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
攻克CakePHP系列二 表单数据显示
2008/10/22 PHP
php zend 相对路径问题
2009/01/12 PHP
基于pear auth实现登录验证
2010/02/26 PHP
使用php伪造referer的方法 利用referer防止图片盗链
2014/01/20 PHP
ThinkPHP实现事务回滚示例代码
2014/06/23 PHP
PHP模拟asp.net的StringBuilder类实现方法
2015/08/08 PHP
Yii2中简单的场景使用介绍
2017/06/02 PHP
详细解读php的命名空间(一)
2018/02/21 PHP
PDO::errorCode讲解
2019/01/28 PHP
filemanage功能中用到的lib.js
2007/04/08 Javascript
jquery cookie插件代码类
2009/05/26 Javascript
js获取浏览器基本信息大全
2014/11/27 Javascript
Node.js中Request模块处理HTTP协议请求的基本使用教程
2016/03/31 Javascript
JS数字千分位格式化实现方法总结
2016/12/16 Javascript
vue2.x 父组件监听子组件事件并传回信息的方法
2017/07/17 Javascript
浅析JS抽象工厂模式
2017/12/14 Javascript
JQuery选中select组件被选中的值方法
2018/03/08 jQuery
详解一个基于react+webpack的多页面应用配置
2019/01/21 Javascript
javascript之分片上传,断点续传的实际项目实现详解
2019/09/05 Javascript
python Selenium爬取内容并存储至MySQL数据库的实现代码
2017/03/16 Python
Python从单元素字典中获取key和value的实例
2018/12/31 Python
PyQt5 加载图片和文本文件的实例
2019/06/14 Python
python字典的常用方法总结
2019/07/31 Python
基于python操作ES实例详解
2019/11/16 Python
python对 MySQL 数据库进行增删改查的脚本
2020/10/22 Python
pytorch简介
2020/11/11 Python
Canvas与图片压缩的示例代码
2017/11/28 HTML / CSS
高中生学期学习自我评价
2014/02/24 职场文书
公司聘任书模板
2014/03/29 职场文书
大学生毕业求职信
2014/06/12 职场文书
创新社会管理心得体会
2014/09/12 职场文书
2015年安全月活动总结
2015/03/26 职场文书
2015大学生入党个人自传
2015/06/26 职场文书
2015年学校消防安全工作总结
2015/10/14 职场文书
Go timer如何调度
2021/06/09 Golang
MySql数据库 查询时间序列间隔
2022/05/11 MySQL