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 相关文章推荐
wxpython 学习笔记 第一天
Mar 16 Python
Python实现matplotlib显示中文的方法详解
Feb 06 Python
python  Django中的apps.py的目的是什么
Oct 15 Python
关于Django ForeignKey 反向查询中filter和_set的效率对比详解
Dec 15 Python
Python如何爬取实时变化的WebSocket数据的方法
Mar 09 Python
python浪漫表白源码
Apr 05 Python
Python使用Pandas库实现MySQL数据库的读写
Jul 06 Python
Python连接Hadoop数据中遇到的各种坑(汇总)
Apr 14 Python
python简单实现最大似然估计&amp;scipy库的使用详解
Apr 15 Python
python程序如何进行保存
Jul 03 Python
Python3爬虫关于代理池的维护详解
Jul 30 Python
python使用建议与技巧分享(二)
Aug 17 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
PHP5.0对象模型探索之抽象方法和抽象类
2006/09/05 PHP
php画图实例
2014/11/05 PHP
利用PHP如何写APP接口详解
2016/08/23 PHP
php使用redis的有序集合zset实现延迟队列应用示例
2020/02/20 PHP
javascript实现的鼠标链接提示效果生成器代码
2007/06/28 Javascript
javascript contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
2010/02/04 Javascript
JQuery 绑定select标签的onchange事件,弹出选择的值,并实现跳转、传参
2011/01/06 Javascript
jquery 跨域访问问题解决方法(笔记)
2011/06/08 Javascript
批量修改标签css样式以input标签为例
2014/07/31 Javascript
JavaScript中Number.NEGATIVE_INFINITY值的使用详解
2015/06/05 Javascript
JS实现动态增加和删除li标签行的实例代码
2016/10/16 Javascript
Vue实现数字输入框中分割手机号码的示例
2017/10/10 Javascript
React styled-components设置组件属性的方法
2018/08/07 Javascript
Angular6 Filter实现页面搜索的示例代码
2018/12/02 Javascript
vuejs移动端实现div拖拽移动
2019/07/25 Javascript
Element Breadcrumb 面包屑的使用方法
2020/07/26 Javascript
Vue页面跳转传递参数及接收方式
2020/09/09 Javascript
JS获取一个字符串中指定字符串第n次出现的位置
2021/02/10 Javascript
[15:41]教你分分钟做大人——灰烬之灵
2015/03/11 DOTA
python实现爬虫下载美女图片
2015/07/14 Python
python并发编程多进程之守护进程原理解析
2019/08/20 Python
Python实现的微信红包提醒功能示例
2019/08/22 Python
浅谈Html5多线程开发之WebWorkers
2018/05/02 HTML / CSS
BrandAlley英国:法国折扣奢侈品网上零售商
2017/07/03 全球购物
白兰氏健康Mall:BRAND’S
2017/11/13 全球购物
Audible英国:有声读物,30天免费试用
2019/10/16 全球购物
DC Shoes俄罗斯官网:美国滑板鞋和服饰品牌
2020/08/19 全球购物
Sunglass Hut巴西网上商店:男女太阳镜
2020/10/04 全球购物
高中打架检讨书
2014/02/13 职场文书
企业演讲比赛主持词
2014/03/18 职场文书
战略合作意向书范本
2014/04/01 职场文书
党支部先进事迹材料
2014/12/24 职场文书
大学生创业,为什么都会选择快餐饮?
2019/08/08 职场文书
一定要知道的 25 个 Vue 技巧
2021/11/02 Vue.js
Python+Selenium自动化环境搭建与操作基础详解
2022/03/13 Python
JavaScript声明变量和数据类型的转换
2022/04/12 Javascript