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逐行读取文件内容的三种方法
Jan 20 Python
使用Python的PIL模块来进行图片对比
Feb 18 Python
Python基于回溯法子集树模板解决旅行商问题(TSP)实例
Sep 05 Python
利用numpy实现一、二维数组的拼接简单代码示例
Dec 15 Python
python爬虫正则表达式之处理换行符
Jun 08 Python
Python3实现的简单三级菜单功能示例
Mar 12 Python
浅谈python图片处理Image和skimage的区别
Aug 04 Python
python multiprocessing模块用法及原理介绍
Aug 20 Python
tensorflow将图片保存为tfrecord和tfrecord的读取方式
Feb 17 Python
Python单例模式的四种创建方式实例解析
Mar 04 Python
python+appium+yaml移动端自动化测试框架实现详解
Nov 24 Python
python中pyqtgraph知识点总结
Jan 26 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和Shell写Hadoop的MapReduce程序
2014/04/15 PHP
PHP实现的简易版图片相似度比较
2015/01/07 PHP
日期函数扩展类Ver0.1.1
2006/09/07 Javascript
DOM精简教程
2006/10/03 Javascript
IE与Firefox在JavaScript上的7个不同句法分享
2011/10/30 Javascript
jquery 漂亮的删除确认和提交无刷新删除示例
2013/11/13 Javascript
JQuery实现鼠标移动到图片上显示边框效果
2014/01/09 Javascript
JavaScript模拟深蓝vs卡斯帕罗夫的国际象棋对局示例
2015/04/22 Javascript
jQuery处理图片加载失败的常用方法
2015/06/08 Javascript
js如何判断访问是来自搜索引擎(蜘蛛人)还是直接访问
2015/09/14 Javascript
js 输入框 正则表达式(菜鸟必看教程)
2017/02/19 Javascript
Angularjs 与 bower安装和使用详解
2017/05/11 Javascript
BootStrap 获得轮播中的索引和当前活动的焦点对象
2017/05/11 Javascript
详解vue-cli快速构建项目以及引入bootstrap、jq
2017/05/26 Javascript
angular 未登录状态拦截路由跳转的方法
2018/10/09 Javascript
详解vue-cli 3.0 build包太大导致首屏过长的解决方案
2018/11/10 Javascript
小程序接口的promise化的实现方法
2019/12/11 Javascript
将Vue组件库更换为按需加载的方法步骤
2020/05/06 Javascript
vue脚手架项目创建步骤详解
2021/03/02 Vue.js
Python二叉搜索树与双向链表转换实现方法
2016/04/29 Python
快速实现基于Python的微信聊天机器人示例代码
2017/03/03 Python
Python3网络爬虫之使用User Agent和代理IP隐藏身份
2017/11/23 Python
pyqt5实现俄罗斯方块游戏
2019/01/11 Python
基于wxPython的GUI实现输入对话框(2)
2019/02/27 Python
详解Python正则表达式re模块
2019/03/19 Python
Python 面向对象之类class和对象基本用法示例
2020/02/02 Python
Python多线程正确用法实例解析
2020/05/30 Python
使用Html5实现异步上传文件,支持跨域,带有上传进度条
2016/09/17 HTML / CSS
Hurley官方网站:扎根于海滩生活方式的全球青年文化品牌
2020/05/18 全球购物
创建卫生先进单位实施方案
2014/03/10 职场文书
硕士生找工作求职信
2014/07/05 职场文书
合作协议书范文
2014/08/20 职场文书
大学生国家助学金感谢信
2015/01/23 职场文书
2015庆祝七一建党节94周年活动总结
2015/03/20 职场文书
mysql sum(if())和count(if())的用法说明
2022/01/18 MySQL
jdbc中自带MySQL 连接池实践示例
2022/07/23 MySQL