使用 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 的一些比较常用和重要的功能介绍完了,如果大家有用心去体会的话,相信可以写出一些非常精妙的校验器出来。

  

时间: 2024-12-23 12:01:01

使用 voluptuous 校验数据的相关文章

struts2 校验数据的有效性 2种方式

Struts2的数据校验: 数据的校验分为客户端校验和服务器端两种: 客户端校验:JS完成的校验.(为了提升用户体验.减少用户的输入错误) 服务器端校验:在后台的校验.(必须的.) 手动编码进行校验: 1.编写一个Action,这个Action必须继承ActionSupport. 2.重写validate方法:---针对Action中的所有方法进行校验. @Override // Struts2提供的数据校验的方法: public void validate() { if(username ==

Struts2 校验数据问题

我们会经常遇到一下问题,例如我在前端输入数据,把数据发送到和后台,我首先要校验这个数据, 比如说:前端必须输入一个日期类型的数据,后端才能正确接收,要是输入一个不是日期型的数据, 那么后端就要把数据打回去,并且提示或者跳转到错误页面.那么怎么去校验呢? f废话不多说,直接添代码,最直观的方法. 前端代码: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%&

在ASP中用“正则表达式对象”来校验数据的合法性

我们在制作网站的时候,尤其是各种电子商务网站,首先都会让用户填写一些表格来获取注册用户的各种信息,因为用户有可能输入各式各样的信息,而有些不符合要求的数据会给我们的后端ASP处理程序带来不必要的麻烦,甚至导致网站出现一些安全问题.因此我们在将这些信息保存到网站的数据库之前,要对这些用户所输入的信息进行数据的合法性校验,以便后面的程序可以安全顺利的执行.所以我们一般会在后端编写一个ASP的校验程序来分析用户输入的数据是否是合法的. 或许有人会问了,使用运行在客户端的JavaScript不是可以更好

Mingyang.net:用注解校验数据

注解校验依赖的是javax.validation和hibernate-validaton. <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <grou

struts2学习笔记--使用Validator校验数据

我们在进行一些操作是需要对用户的输入数据进行验证,比如网站的注册,需要对各个数据项进行数据校验,Struts2提供了一些默认的校验器,比如数字的检测,邮箱的检测,字符串长度的检测等等. 常用的Validator 校验器 作用  required  必填校验器,要求字段必须有值  requiredstring 必填字符串校验器,要求必须有值且长度大于0,即不能是空字符串.默认会去掉字符串前后空格 参数fieldName:该参数指定校验的字段名称,如果是字段校验,则不用指定该参数 参数trim:该参

dat类型文件入库后校验数据有问题

一.问题: dat或者txt文件入库后,字段进行正则校验报出不应该出现的错误 二.排查: (1)根据报出的错误,把错误日志中的字串单独提取出来,进行正则校验发现没有问题 (2)可以想到,要不是程序问题,或者是错误日志抓取没有真实的反映当时的错误情况 (3)而报错的这个文件是个例,排除了程序问题 (4)那么,进行字段正则校验的时候到底发生了什么? (5)提取流入校验流程的数据,也就是文本文件导入数据库后的字段数据 (6)直接数据库执行从表里提取字段的校验会出现错误,那么就是这个字段隐藏了数据信息

Java自定义注解反射校验数据

package com.annotations.ecargo; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUN

《Java从入门到放弃》入门篇:springMVC数据校验

昨天我们扯完了数据传递,今天我们来聊聊数据校验的问题.来,跟着我一起读:计一噢叫,一按艳. 在springMVC中校验数据也非常简单,spring3.0拥有自己独立的数据校验框架,同时支持JSR303标准的校验框架. Spring的DataBinder在进行数据绑定时,会同时调用校验框架完成数据校验工作. 具体使用步骤如下: 1)导入数据校验的JAR包 2)在springmvc的配置文件中添加校验Bean 3)修改实体类,在属性上加上校验的注解 4)修改昨天的login4方法,加上校验的相关代码

用特性来实现数据的校验

在网站开发中,往往需要对用户输入的数据进行校验.而为了保持数据的完整性,我们需要进行客户端和服务端的双重校验.客户端的校验一般由js来完成,本文主要介绍利用特性完成服务器端的数据校验. 什么是特性? 超市中有各种各样的商品,商品上贴有标签.标签上可能有商品的名称,价格,种类等信息.我们要购买一样东西前,一般先会看标签,了解更多的信息.当然主要是价格,万一钱没带够呢?:) 如果把类当做商品,那么特性就是贴在商品上的标签.特性给我们提供了更多类相关的信息.[Serializable] 就是在C#中常