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 相关文章推荐
pydev使用wxpython找不到路径的解决方法
Feb 10 Python
Python中模拟enum枚举类型的5种方法分享
Nov 22 Python
python创建进程fork用法
Jun 04 Python
浅谈使用Python变量时要避免的3个错误
Oct 30 Python
python如何发布自已pip项目的方法步骤
Oct 09 Python
python 将list转成字符串,中间用符号分隔的方法
Oct 23 Python
python爬虫 urllib模块反爬虫机制UA详解
Aug 20 Python
Python 导入文件过程图解
Oct 15 Python
关于pandas的离散化,面元划分详解
Nov 22 Python
Python编程快速上手——Excel表格创建乘法表案例分析
Feb 28 Python
Python基于yield遍历多个可迭代对象
Mar 12 Python
Windows10+anacond+GPU+pytorch安装详细过程
Mar 24 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下intval()和(int)转换使用与区别
2008/07/18 PHP
PHP封装的一个支持HTML、JS、PHP重定向的多功能跳转函数
2014/06/19 PHP
jQuery 美元符冲突的解决方法
2010/03/28 Javascript
Extjs Gird 支持中文拼音排序实现代码
2013/04/15 Javascript
JQueryiframe页面操作父页面中的元素与方法(实例讲解)
2013/11/19 Javascript
简介AngularJS中$http服务的用法
2016/02/06 Javascript
基于Angularjs实现分页功能
2016/05/30 Javascript
Extjs 点击复选框在表格中增加相关信息行
2016/07/12 Javascript
提高Web性能的前端优化技巧总结
2017/02/27 Javascript
基于javaScript的this指向总结
2017/07/22 Javascript
react-native ListView下拉刷新上拉加载实现代码
2017/08/03 Javascript
js模块加载方式浅析
2017/08/12 Javascript
vue与bootstrap实现时间选择器的示例代码
2017/08/26 Javascript
vue.js学习笔记之v-bind和v-on解析
2018/05/03 Javascript
快速解决vue-cli在ie9+中无效的问题
2018/09/04 Javascript
深入理解JavaScript 中的执行上下文和执行栈
2018/10/23 Javascript
npm 常用命令详解(小结)
2019/01/17 Javascript
在vue项目中使用codemirror插件实现代码编辑器功能
2019/08/27 Javascript
vue组件中节流函数的失效的原因和解决方法
2020/12/02 Vue.js
python实现问号表达式(?)的方法
2013/11/27 Python
python机器学习理论与实战(五)支持向量机
2018/01/19 Python
详解Django之admin组件的使用和源码剖析
2018/05/04 Python
Pandas之Dropna滤除缺失数据的实现方法
2019/06/25 Python
python实现最大子序和(分治+动态规划)
2019/07/05 Python
关于Python内存分配时的小秘密分享
2019/09/05 Python
Python虚拟环境库virtualenvwrapper安装及使用
2020/06/17 Python
Python中使用aiohttp模拟服务器出现错误问题及解决方法
2020/10/31 Python
python help函数实例用法
2020/12/06 Python
用缩写的指针比较"if(p)" 检查空指针是否可靠?如果空指针的内部表达不是0会怎么样?
2014/01/05 面试题
2015感人爱情寄语
2015/02/26 职场文书
求职简历自我评价范文
2015/03/10 职场文书
国王的演讲观后感
2015/06/03 职场文书
FP-growth算法发现频繁项集——发现频繁项集
2021/06/24 Python
【海涛dota解说】DCG联赛第一周 LGD VS DH
2022/04/01 DOTA
一文搞懂Redis中String数据类型
2022/04/03 Redis
AndroidStudio图片压缩工具ImgCompressPlugin使用实例
2022/08/05 Java/Android