使用 voluptuous 校验数据
在 Python 中,我们经常需要对参数进行校验,这是我们有好多种方法,例如写很多 if 啊,或者写正则表达式啊等等,技巧高的人可以写得很巧妙,而技巧一般的人呢,可能会写得很冗长,例如我,经常就不能很好得处理参数校验的代码。
所以我就不断得寻找,终于最近发现了一个不错的 python 参数校验 lib,叫做 voluptuous。名字可能有点难记,而且英文翻译过来的中文还不怎么好听,但是非常好用。下面就逐渐带大家尝试一下 voluptuous 库的妙用。
安装 voluptuous 要用之前,肯定要先安装的啦,安装这一步很简单,还是按照往常一般使用 pip 搞定。我使用的是当前的最新版 0.8.8: pip install voluptuous==0.8.8 尝试 voluptuous 首先,想来一个最为常见的,就是校验参数的类型,我这里假设参数都是以 json 格式进行传递的,json 格式在 python 中又可以表现为字典(dict),所以这里就不做区分了。
以官网的日志为例,使用分页的参数为例子,校验参数的类型,首先,我们要求参数的类型,查询的字段q必须为字符串,分页大小per_page必须为数字,页码page必须为数字。
那么,使用 voluptuous 后,可以这样写: from voluptuous import Schema s = Schema({ 'q': str, 'per_page': int, 'page': int }) 这就表示了我们刚才的需求:查询的字段q必须为字符串,分页大小per_page必须为数字,页码page必须为数字。
那么,现在,假设客户端传过来了一组参数: {"q": "hello", "page": 10, "per_page": 20 } 那么,我们要怎么来校验呢?也很简单: from voluptuous import Schema s = Schema({ 'q': str, 'per_page': int, 'page': int }) print s({"q": "hello", "page": 10, "per_page": 20 }) 这里可以看到,我们使用客户端传递过来的参数作为参数,调用了我们使用既定模板创建的对象,然后直接把他打印出来,如果你跑过这段代码,你会发现结果如下: {"q": "hello", "page": 10, "per_page": 20 } 没错, voluptuous 就是将校验通过的参数返回了。就是这么简单。 那这时,你可能要问了,如果校验不通过的参数怎么办,我要怎么处理,下面就演示一下如果传递的参数是: {"q": "hello", "page": "world", "per_page": 20 } 这样的话,要怎么来处理校验不通过的问题,其实,当校验不通过的时候,Schema 会抛出一个异常,然后我们可以通过捕获这个异常来确定校验失败的问题,例如:
try: print s({"q": "hello", "page": "world","per_page": 20}) except MultipleInvalid as e: print "error: {} occur while parse args".format(e.errors) 当你执行这段代码之后,你会发现打印出来的内容是: error: [TypeInvalid('expected int',)] occur while parse args
我们就知道参数是有问题的,需要客户端确认。 更进一步 ok,这就是一个简单的校验,下面我们进行更复杂的校验,我们现在不仅要保证参数的类型正确,我们还需要保证查询参数一定要有,另外两个参数可有可无。那么我们可以怎么做呢? 其实,也很简单,就是给必须的参数加上一个 Required 关键字,例如这样:
from voluptuous import Schema, Required required_s = Schema({ Required('q'): str, 'per_page': int, 'page': int }) 然后,我们可以尝试一下加入什么都不传,会发生什么事:
try: print required_s({}) except MultipleInvalid as e: print "error: {} occur while parse with required args".format(e.errors) 很明显,你跑一遍就知道了,这段代码会抛出这个异常: error: [RequiredFieldInvalid('required key not provided',)] occur while parse with required args 这个时候,我们再贪心一点,我们觉得参数必须还不够,还不能有多余的参数,什么参数都塞过来,浪费我内存啊,过滤这个应该和刚才的参数必须有一样简单吧?
是的,不过这时因为不是对单独一个参数起作用了,所以需要放在 Schema 的参数里面,这个参数叫做 extras,例如下面这段就是表示不要多余的参数: not_allow_extra_s = Schema({ 'q': str, 'per_page': int, 'page': int }, extra=False) 然后我们尝试一下:
try: print not_allow_extra_s({"q": "hello", "unknown": "key"}) except MultipleInvalid as e: print "error: {} occur while parse with no extras args".format(e.errors) 结果也很简单:
error: [Invalid('extra keys not allowed',)] occur while parse with no extras args 其实,Schema 默认就是不允许有多余参数的,如果我们想要多余的参数,则需要显式得将这个参数设置为 True,表示允许有多余的参数。
现在我们已经知道一些用法了,但是,我们觉得只控制类型不够,我们还想控制一下参数的长度,例如查询的参数不能超过 10 个字符,那么样怎么做了? 下面这段代码就自定义了一个校验值不能超过 10 个字符的 str 类型: def less_than_10(value): if isinstance(value, str) and len(value) 校验函数很简单,接受一个参数,也就是要校验的值,然后,如果校验成功就返回这个值,否则就抛出一个 Invalid 的异常。这样 Schema 就知道是否校验通过了。
其实,你可能会想,如果这里校验通过后我返回的不是参数的值会怎样?如果你有这个想法,我很佩服。
确实,如果这里不返回参数的值,Schema 也会认为是校验通过的,而且 Schema 会将你的返回值返回。那么想到这里,你是不是有一些更加强大的想法?好吧,不知道你有没有,我这里告知一下,可以通过这个方法来进行数据转换。
假如,我们的查询只支持大写字母,但是我们认为客户端传过来是小写字母的时候也是有效的,那么,我们就需要将客户端传递过来的参数进行转换,转成大写字母,那么,我们可以这样写: def convert_letter(value): if isinstance(value, str): return value.upper() raise Invalid("not valid string") transformation_s = Schema({ Required('q'): convert_letter, 'per_page': int, 'page': int }) print transformation_s({'q': 'hello'})
然后,我们看一下输出: {'q': 'HELLO'} 已经变成了大写了。 好吧,到此已经将 voluptuous 的一些比较常用和重要的功能介绍完了,如果大家有用心去体会的话,相信可以写出一些非常精妙的校验器出来。
使用 voluptuous 校验数据的更多相关文章
- struts2 校验数据的有效性 2种方式
Struts2的数据校验: 数据的校验分为客户端校验和服务器端两种: 客户端校验:JS完成的校验.(为了提升用户体验.减少用户的输入错误) 服务器端校验:在后台的校验.(必须的.) 手动编码进行校验: ...
- Struts2 校验数据问题
我们会经常遇到一下问题,例如我在前端输入数据,把数据发送到和后台,我首先要校验这个数据, 比如说:前端必须输入一个日期类型的数据,后端才能正确接收,要是输入一个不是日期型的数据, 那么后端就要把数据打 ...
- springmvc JSR303 Validate 注解式,校验数据
参考:http://www.cnblogs.com/liukemng/category/578644.html 先进行配置: <!-- 默认的注解映射的支持 --> <mvc:ann ...
- django基础之day09,Forms组件在程序中做了哪些事? 校验数据、渲染标签、展示信息
******************************* Forms组件 *************************************************** Forms组件在 ...
- 使用ModelForm校验数据唯一性
在设计模型类的时候,将指定字段设置unique=true属性,可以保证该字段在数据库中的唯一性. 使用ModelForm可以将指定模型类快速生成表单元素.在提交数据后,使用is_valid()校验时, ...
- 使用@Validated校验数据(除数据库做辅助)
一.controller层 /** * 使用@Validated来进行校验 * @author HuangJingNa * @date 2019年12月23日 下午6:02:20 * * @param ...
- struts2学习笔记--使用Validator校验数据
我们在进行一些操作是需要对用户的输入数据进行验证,比如网站的注册,需要对各个数据项进行数据校验,Struts2提供了一些默认的校验器,比如数字的检测,邮箱的检测,字符串长度的检测等等. 常用的Vali ...
- C#和C实现通过CRC-16 (Modbus)获取CRC值并校验数据(代码)
文章首发于浩瀚先森博客 CRC的全称为Cyclic Redundancy Check,中文名称为循环冗余校验.它是一类重要的线性分组码,编码和解码方法简单,检错和纠错能力强,在通信领域广泛地用于实现差 ...
- Jmeter学习之-从数据库取出数据并且校验数据是否准确
https://www.cnblogs.com/wuyonghuan/p/7479582.html 应用场景:调用某个接口像数据库中插入数据,需要在接口调用完成后查看数据更新或插入的数据是否正确的时候 ...
随机推荐
- 一个Shell小脚本——旋转的斜杠
话不多说,请从代码中寻找乐趣吧! #!/bin/bash #----中断计数器----# incr= #----旋转的斜杠----# spin="/-\|" echo -en &q ...
- <c:if>判断两个<c:forEach>里的数据是否相等
问题:两个<c:forEach>嵌套,里面循环的值和外面的值进行比较(里层里的PARENTID是否等于外层的ID),如果相等就显示. <c:forEach items="$ ...
- CI持续集成
CI持续集成 “我的TDD实践”系列之CI持续集成 写在前面: 我的TDD实践这几篇文章主要是围绕测试驱动开发所展开的,其中涵盖了一小部分测试理论,更多的则是关注工具的使用及环境的搭建,做到简单实践先 ...
- boost xpressive 例子
1.效果图: 我有一个wordpress博客,每次在csdn上写完博客,都需要复制到wordpress中,还需要手动修改<pre>和图片地址,比较麻烦,所以做了这个工具. 功能: 1.把C ...
- Kendo UI开发教程(7): Kendo UI 模板概述
Kendo UI 框架提供了一个易用,高性能的JavaScript模板引擎.通过模板可以创建一个HTML片段然后可以和JavaScript数据合并成最终的HTML元素. Kendo 模板侧重于UI显示 ...
- android 常用资料
网上收集保存的一些常用的android资料,写得都比较不错,和大家分享下,共同学习: _ android ListView美化.docx androidshape.docx android_textv ...
- c++字符串连接方法大观
c++字符串连接方法大观 抛砖引玉: springf(config_itemID[i],"ItemID%s_%d",i,i); 大家说说自己都用什么方法,个有什么利弊呢?
- 机器学习( Machine Learning)的定义
关于机器学习有两个相关的定义: 1)给计算机赋予没有固定编程的学习能力的研究领域. 2)一种计算机的程序,能从一些任务(T)和性能的度量(P),经验(E)中进行学习.在学习中,任务T的性能P能够随着P ...
- 如何成为一名hacker?
很多人问我如何成为黑客,一般来说我总是会扯一大堆废话,告诉他们要时刻保持好奇心,要学会打破规则挑战权威之类的. 但这类话肯定不是提问者想听的.我揣摩了一下他们的心情,他们想问的应该是这个问题:如何学习 ...
- 间隔Ns请求某函数并且有timeout
实现方案: 1. 递归调用 2.timer:apply_interval() 3.gen_server来写 时间timeout怎么实现: 1.开始时间存入ets表中 2.put,get方法放入进程字典 ...