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编写的最短路径算法
Mar 25 Python
pyqt5实现绘制ui,列表窗口,滚动窗口显示图片的方法
Jun 20 Python
python写日志文件操作类与应用示例
Jul 01 Python
django基础学习之send_mail功能
Aug 07 Python
Python使用百度api做人脸对比的方法
Aug 28 Python
DJango的创建和使用详解(默认数据库sqlite3)
Nov 18 Python
利用python3 的pygame模块实现塔防游戏
Dec 30 Python
Python面向对象封装操作案例详解
Dec 31 Python
python统计函数库scipy.stats的用法解析
Feb 25 Python
PyCharm永久激活方式(推荐)
Sep 22 Python
Python实现自动打开电脑应用的示例代码
Apr 17 Python
如何通过python实现IOU计算代码实例
Nov 02 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
让你同时上传 1000 个文件 (一)
2006/10/09 PHP
php使用pack处理二进制文件的方法
2014/07/03 PHP
PHP自动重命名文件实现方法
2014/11/04 PHP
微信公众平台开发教程②微信端分享功能图文详解
2019/04/10 PHP
33个优秀的 jQuery 图片展示插件分享
2012/03/14 Javascript
js获取html参数及向swf传递参数应用介绍
2013/02/18 Javascript
js数组的基本用法及数组根据下标(数值或字符)移除元素
2013/10/20 Javascript
JQuery调用绑定click事件的3种写法
2015/03/28 Javascript
详解Angular.js数据绑定时自动转义html标签及内容
2017/03/30 Javascript
vue组件之间通信方式实例总结【8种方式】
2019/02/22 Javascript
jquery弹窗时禁止body滚动条滚动的例子
2019/09/21 jQuery
微信小程序语音同步智能识别的实现案例代码解析
2020/05/29 Javascript
jQuery实现带进度条的轮播图
2020/09/13 jQuery
[46:57]EG vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python merge、concat合并数据集的实例讲解
2018/04/12 Python
Python 实现删除某路径下文件及文件夹的实例讲解
2018/04/24 Python
Python英文文本分词(无空格)模块wordninja的使用实例
2019/02/20 Python
python字典的setdefault的巧妙用法
2019/08/07 Python
python将图片转base64,实现前端显示
2020/01/09 Python
Pycharm激活码激活两种快速方式(附最新激活码和插件)
2020/03/12 Python
Python SQLAlchemy库的使用方法
2020/10/13 Python
在印度上传处方,在线订购药品:Medlife
2019/03/28 全球购物
英国玛莎百货澳大利亚:Marks & Spencer Australia
2019/08/30 全球购物
都柏林通行卡/城市通票:The Dublin Pass
2020/02/16 全球购物
C语言50道问题
2014/10/23 面试题
活动策划求职信模板
2014/04/21 职场文书
节水标语大全
2014/06/11 职场文书
2014年无财产无子女离婚协议书范本
2014/10/09 职场文书
社区六一儿童节活动总结
2015/02/11 职场文书
2015年实习班主任工作总结
2015/04/23 职场文书
工地食品安全责任书
2015/05/09 职场文书
实验室安全管理制度
2015/08/05 职场文书
财务人员入职担保书
2015/09/22 职场文书
创业计划书之家教托管
2019/09/25 职场文书
Python入门学习之类的相关知识总结
2021/05/25 Python
MySQL日期时间函数知识汇总
2022/03/17 MySQL