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 闭包的使用方法
Sep 07 Python
python difflib模块示例讲解
Sep 13 Python
python3使用requests模块爬取页面内容的实战演练
Sep 25 Python
django实现登录时候输入密码错误5次锁定用户十分钟
Nov 05 Python
用Python实现筛选文件脚本的方法
Oct 27 Python
Python实现去除列表中重复元素的方法总结【7种方法】
Feb 16 Python
关于Flask项目无法使用公网IP访问的解决方式
Nov 19 Python
基于Python检测动态物体颜色过程解析
Dec 04 Python
Python图像处理库PIL的ImageFont模块使用介绍
Feb 26 Python
python 给图像添加透明度(alpha通道)
Apr 09 Python
Python3 搭建Qt5 环境的方法示例
Jul 16 Python
教你用python控制安卓手机
May 13 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 面向对象 final类与final方法
2010/05/05 PHP
php实现Linux服务器木马排查及加固功能
2014/12/29 PHP
PHP使用内置函数file_put_contents写入文件及追加内容的方法
2015/12/07 PHP
Thinkphp5 自定义上传文件名的实现方法
2019/07/23 PHP
Yii框架中用response保存cookie,用request读取cookie的原理解析
2019/09/04 PHP
File文件控件,选中文件(图片,flash,视频)即立即预览显示
2009/04/09 Javascript
用jquery实现学校的校历(asp.net+jquery ui 1.72)
2010/01/01 Javascript
一个简单的jquery进度条示例
2014/04/28 Javascript
实例分析js和C#中使用正则表达式匹配a标签
2014/11/26 Javascript
体验jQuery和AngularJS的不同点及AngularJS的迷人之处
2016/02/02 Javascript
百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
2016/02/19 Javascript
前端页面文件拖拽上传模块js代码示例
2017/05/19 Javascript
JS仿QQ好友列表展开、收缩功能(第一篇)
2017/07/07 Javascript
jquery animate动画持续运动的实例
2017/11/29 jQuery
利用nodeJs anywhere搭建本地服务器环境的方法
2018/05/12 NodeJs
Vue 之孙组件向爷组件通信的实现
2019/04/23 Javascript
Python素数检测的方法
2015/05/11 Python
Python获取一个用户名的组ID过程解析
2019/09/03 Python
如何在Windows中安装多个python解释器
2020/06/16 Python
基于K.image_data_format() == 'channels_first' 的理解
2020/06/29 Python
用python制作个音乐下载器
2021/01/30 Python
html5音频_动力节点Java学院整理
2018/08/22 HTML / CSS
Monnier Freres中文官网:法国领先的奢侈品配饰在线零售商
2017/11/01 全球购物
利达恒信公司.NET笔试题面试题
2016/03/05 面试题
广告学专业毕业生自荐信
2013/09/24 职场文书
汽车技术服务与营销专业在籍生自荐信
2013/09/28 职场文书
质检部岗位职责
2013/11/11 职场文书
四查四看整改措施
2014/09/19 职场文书
认错检讨书
2014/10/02 职场文书
求职信格式范文
2015/03/19 职场文书
立案决定书范文
2015/06/24 职场文书
2019个人工作态度自我评价
2019/04/24 职场文书
使用HTML+Css+transform实现3D导航栏的示例代码
2021/03/31 HTML / CSS
MySQL 8.0 驱动与阿里druid版本兼容问题解决
2021/07/01 MySQL
关于Spring配置文件加载方式变化引发的异常详解
2022/01/18 Java/Android
sql时间段切分实现每隔x分钟出一份高速门架车流量
2022/02/28 SQL Server