用于Python的流畅且易于使用的数据验证器
项目描述
TL;DR 使用voluptuous代替
演示
Onctuous 是一个流畅且易于使用的验证工具,您一定会喜欢使用。最初基于Alec Thomas的 Voluptuous 代码,我们首先修复了长期存在的问题,如Python内置冲突,并添加了对默认值的支持。
- Onctuous 的目标是使其简单流畅。
您可以编写自己的验证器
您可以指定默认值。最好的是?它们不需要自己通过验证
您可以编写可读的代码。这不是基于json模式规范,故意为之
您可以使用Onctuous来验证列表、标量(常规变量)或字典。为此,您需要定义所谓的模式,并用输入调用模式进行验证。在成功的情况下,它将返回验证后的输入,可能根据您的规则进行过滤或编辑
安装
$ pip install onctuous
开发
$ hg clone ssh://hg@bitbucket.org/Ludia/onctuous $ pip install nose nosexcover coverage mock $ python setup.py develop $ nosetests
为什么使用Onctuous而不是其他验证库?
它是
可读的
容易的
- 验证器是简单的可调用对象
不需要子类化任何东西,只需使用一个函数。
- 错误是简单的异常。
验证器只需抛出 Invalid(msg)并期望用户获得有用的消息。
- 模式是基本的Python数据结构。
如果您的数据应该是一个整数键到字符串的字典?{int: str}做您期望的事情。整数、浮点数或字符串的列表?[int, float, str]。
- 从一开始就为验证不仅仅是表单而设计。
嵌套数据结构以与其他任何类型相同的方式处理。需要字典列表?[{}]
- 一致性。
模式中的类型按类型进行检查。值按值进行比较。可调用对象被调用以进行验证。简单。
示例用法
验证标量
from onctuous import Schema validate_is_int = Schema(int) # Validate 42 (this will run fine) validated = validate_is_int(42) # Validate "toto" (this will raise ``InvalidList`` containing a list of errors) validated = validate_is_int("toto")
验证列表
使用相同的思想,您可以验证int列表
from onctuous import Schema validate_is_int_list = Schema([int]) # This will run fine validated = validate_is_int_list([42, 2, 7]) # This will raise ``InvalidList`` containing a list of errors validated = validate_is_int_list([2, 7, "toto"])
但我们可以使用捆绑的验证器之一并检查URL看起来是否有效,甚至可以提供自定义错误消息!
from onctuous import Schema, Url validate_is_urls = Schema([Url(msg="Ooops, this is *not* a valid URL")]) # This will run fine validated = validate_is_urls(["www.example.com", "ftp://user:pass@ftp.example.com:42/toto?weird/path"]) # This will raise ``InvalidList`` containing a list of errors validated = validate_is_urls([2, 7, "toto"])
验证字典
再次,这同样是一个概念,有一些更优雅的用法。例如,这里是一个基本的用户模式
from onctuous import Schema, Url validate_user = Schema({ 'firstname': unicode, 'lastname': unicode, 'age': int, 'website': Url(msg="Ooops, this is *not* a valid URL"), }) # use it...
但是等等,我不希望有负年龄,对吧?
from onctuous import Schema, Url, InRange, All validate_user = Schema({ 'firstname': unicode, 'lastname': unicode, 'age': All(int, InRange(min=0, msg="Uh, ages can not be negative...")), 'website': Url(msg="Ooops, this is *not* a valid URL"), }) # use it...
您注意到这是如何使用All来指定必须同时满足int和range条件吗?
如果我想要将“网站”字段设置为可选的怎么办?让我介绍一下Markers
from onctuous import Schema, Url, InRange, All, Optional validate_user = Schema({ 'firstname': unicode, 'lastname': unicode, 'age': All(int, InRange(min=0, msg="Uh, ages can not be negative...")), Optional('website'): Url(msg="Ooops, this is *not* a valid URL"), }) # use it...
您也可以使用带有默认值的“Required”标记。如果您不想花费大量时间编写if key in data...,这将非常有用。
from onctuous import Schema, Url, InRange, All, Required validate_user = Schema({ 'firstname': unicode, 'lastname': unicode, 'age': All(int, InRange(min=0, msg="Uh, ages can not be negative...")), Required('website', "#"): Url(msg="Ooops, this is *not* a valid URL"), }) # use it...
值得注意的是,提供的默认值不需要通过验证。您可以用它作为“标记”在您的应用程序中进一步使用。
嵌套和高级验证
您可以嵌套模式。您实际上已经在之前的示例中做到了这一点,其中标量被嵌套到字典或列表中。但您可以根据需要任意地嵌套列表到字典,反之亦然。
例如,假设您正在编写一篇文章,显然它有一个作者和一些长度在3到20个字符之间的标签。
from onctuous import Schema, All, Required, Length, InRange # Same schema as user above. I just removed the Schema instanciation but # could have kept it. It's just more natural user = { 'firstname': unicode, 'lastname': unicode, 'age': All(int, InRange(min=0, msg="Uh, ages can not be negative...")), Required('website', "#"): Url(msg="Ooops, this is *not* a valid URL"), } validate_post = Schema({ 'title': unicode, 'body': unicode, 'author': user, # look how you can split a schema into re-usable chunks! Optional('tags'): [All(unicode, Length(min=3, max=20))], Required('website', "#"): Url(msg="Ooops, this is *not* a valid URL"), }) # use it...
嵌套就到这里。
您还可以使用Extra特殊键来允许存在额外的字段,同时仍然有效。
在实例化模式时,还有一个全局的required和extra参数可以可选地设置。它们都默认为False
更进一步
有大量的捆绑验证器,请查看完整的API文档以获取完整列表
要求
Python 2.7.x
nose, nosexcover, coverage, mock用于测试