繼續(xù)記錄最近學習的python數(shù)據(jù)驗證工具生蚁。
voluptuous與validator的使用比較相似,注意是validator,不是validators瘸洛。validator和validators是兩個不同的python數(shù)據(jù)驗證的庫。
Voluptuous的目標:
1次和、簡潔
2反肋、支持復雜的數(shù)據(jù)結構
3、提供有價值的錯誤信息
一踏施、安裝
$ pip install voluptuous
二石蔗、數(shù)據(jù)驗證
1、和validator類似畅形,為了驗證數(shù)據(jù)养距,我們需要先定義一個模式scheme
.
>>> from voluptuous import Schema
>>> schema = Schema({
'q': str,
'per_page': int,
'page': int,
})
這個模式要求待檢查的數(shù)據(jù),字段"q"
需要時str
類型日熬,字段"per_page"
需要是int
類型棍厌,字段"page"
需要是int
類型。
如果我們要驗證的數(shù)據(jù)是
data = {
"q": "hello world",
"per_page": 20,
"page": 10
}
只需要
>>> schema(data)
{'q': 'hello world', 'per_page': 20, 'page': 10}
如果驗證通過竖席,則返回驗證的數(shù)據(jù)耘纱。那么,如果驗證的參數(shù)不能通過呢毕荐?我們來看一個驗證失敗的例子束析。
failure_data = {
"q": "hello world",
"per_page": "hi",
"page": 10
}
>>> schema(failure_data)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "D:\Python27\lib\site-packages\voluptuous\schema_builder.py", line 221, i
n __call__
return self._compiled([], data)
File "D:\Python27\lib\site-packages\voluptuous\schema_builder.py", line 538, i
n validate_dict
return base_validate(path, iteritems(data), out)
File "D:\Python27\lib\site-packages\voluptuous\schema_builder.py", line 370, i
n validate_mapping
raise er.MultipleInvalid(errors)
voluptuous.error.MultipleInvalid: expected int for dictionary value @ data['per_
page']
這里字段 "per_page"的值是字符串,不是int類型憎亚,驗證失敗员寇,程序報錯弄慰。
但是有時在一個程序里,我們會做多個驗證蝶锋,我們只是希望得到每一個驗證的結果陆爽,成功or失敗,不希望因為一處失敗扳缕,而影響后面程序的執(zhí)行墓陈。這種情況下,我們可以在程序中捕獲異常第献,得到錯誤信息贡必。
demo.py
from voluptuous import Schema, MultipleInvalid
schema = Schema({
'q': str,
'per_page': int,
'page': int,
})
failure_data = {
"q": "hello world",
"per_page": "hi",
"page": 10
}
try:
schema(failure_data)
except MultipleInvalid as e:
print e.errors
>>> python demo.py
[TypeInvalid('expected int',)]
從e.errors
可以很清晰知道驗證時,發(fā)生了類型驗證錯誤庸毫。
2仔拟、在驗證的過程中,有時我們需要數(shù)據(jù)必須含有某一個字段飒赃,這時可以使用Required.
以上面的例子為例 :
schema = Schema({
'q': str,
'per_page': int,
'page': int,
})
data = {
"q": "hello world",
"page": 10
}
>>> schema(data)
{'q': 'hello world', 'page': 10}
data
中沒有'per_page'
字段利花,驗證依然是成功的;如果我們需要data中必須含有'per_page'
字段载佳,那么schema
可以這樣定義:
from voluptuous import Required
schema = Schema({
'q': str,
Required('per_page'): int,
'page': int,
})
data = {
"q": "hello world",
"page": 10
}
>>>schema(data)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "D:\Python27\lib\site-packages\voluptuous\schema_builder.py", line 221, i
n __call__
return self._compiled([], data)
File "D:\Python27\lib\site-packages\voluptuous\schema_builder.py", line 538, i
n validate_dict
return base_validate(path, iteritems(data), out)
File "D:\Python27\lib\site-packages\voluptuous\schema_builder.py", line 370, i
n validate_mapping
raise er.MultipleInvalid(errors)
voluptuous.error.MultipleInvalid: required key not provided @ data['per_page']
此時data中缺少'per_page'
字段炒事,程序報錯。
3蔫慧、通常我們不僅需要判斷數(shù)據(jù)字段是否存在挠乳,類型是否正確,還會對字符串或列表長度進行驗證姑躲,對數(shù)據(jù)值的范圍進行驗證睡扬。我們可以將對一個字段
的多項驗證用All
封裝起來。
>>> from voluptuous import Required, All, Length, Range
>>> schema = Schema({
... Required('q'): All(str, Length(min=1)),
... Required('per_page', default=5): All(int, Range(min=1, max=20)),
... 'page': All(int, Range(min=0)),
... })
舉兩個驗證失敗的例子:
(1) 數(shù)據(jù)中必須含有'q'
字段
>>> from voluptuous import MultipleInvalid
>>>try:
schema({})
except MultipleInvalid as e:
exc = e
>>> exc.errors
[RequiredFieldInvalid('required key not provided',)]
(2) 字段page
的值必須是一個大于等于0的整數(shù)黍析。
try:
schema({'q': '#topic', 'per_page': 'one'})
except MultipleInvalid as e:
exc = e
>>> exc.errors
[TypeInvalid('expected int',)]
三卖怜、定義schemas
voluptuous的一個優(yōu)點是不僅僅可以驗證字典數(shù)據(jù),也可以驗證一些其他類型的數(shù)據(jù)阐枣。
1马靠、字面值(Literals)
僅僅匹配模式schema
中定義的值與數(shù)據(jù)data
中的值是否相等。
>>> schema = Schema(1)
>>> schema(1)
1
>>> schema(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "D:\Python27\lib\site-packages\voluptuous\schema_builder.py", line 225, i
n __call__
raise er.MultipleInvalid([e])
voluptuous.error.MultipleInvalid: not a valid value
>>> schema = Schema('a string')
>>> schema('a string')
'a string'
2、類型(types)
>>> schema = Schema(int)
>>> schema(1)
1
>>> schema('one')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "D:\Python27\lib\site-packages\voluptuous\schema_builder.py", line 225, i
n __call__
raise er.MultipleInvalid([e])
voluptuous.error.MultipleInvalid: expected int
3、URL’s
>>> from voluptuous import Url
>>> schema = Schema(Url())
>>> schema('http://w3.org')
'http://w3.org'
>>> try:
... schema('one')
... raise AssertionError('MultipleInvalid not raised')
... except MultipleInvalid as e:
... exc = e
>>> str(exc) == "expected a URL"
True
4、列表(Lists)
模式列表中定義了一些合法的值,被檢查的數(shù)據(jù)列表中的每一個值都需要在模式列表中被定義兽掰。
>>> schema = Schema([1, 'a', 'string'])
>>> schema([1])
[1]
>>> schema([1, 1, 1])
[1, 1, 1]
>>> schema(['a', 1, 'string', 1, 'string'])
['a', 1, 'string', 1, 'string']
如果想要定義一個列表,可以包含所有python合法值谓苟,可以使用list
>>> schema = Schema(list)
>>> schema([])
[]
>>> schema([1, 2])
[1, 2]
注意不是使用[]
>>> schema = Schema([])
>>> try:
... schema([1])
... raise AssertionError('MultipleInvalid not raised')
... except MultipleInvalid as e:
... exc = e
>>> str(exc) == "not a valid value"
True
>>> schema([])
[]
5、自定義函數(shù)
>>> from datetime import datetime
>>> def Date(fmt='%Y-%m-%d'):
... return lambda v: datetime.strptime(v, fmt)
>>> schema = Schema(Date())
>>> schema('2013-03-03')
datetime.datetime(2013, 3, 3, 0, 0)
>>> try:
... schema('2013-03')
... raise AssertionError('MultipleInvalid not raised')
... except MultipleInvalid as e:
... exc = e
>>> str(exc) == "not a valid value"
True
6彬祖、字典
待驗證的數(shù)據(jù)中每一個鍵值對需要在字典中已定義,否則品抽,驗證失敗储笑。
>>> schema = Schema({1: 'one', 2: 'two'})
>>> schema({1: 'one'})
{1: 'one'}
如果我們要驗證的數(shù)據(jù)中有額外的鍵值對,并且這種情況不認為是錯誤的圆恤,可以這樣設置突倍。
>>> from voluptuous import ALLOW_EXTRA
>>> schema = Schema({2: 3}, extra=ALLOW_EXTRA)
>>> schema({1: 2, 2: 3})
{1: 2, 2: 3}
如果想要移除額外的鍵,可以使用Schema(..., extra=REMOVE_EXTRA):
>>> from voluptuous import REMOVE_EXTRA
>>> schema = Schema({2: 3}, extra=REMOVE_EXTRA)
>>> schema({1: 2, 2: 3})
{2: 3}
默認情況下盆昙,在字典模式schema
中定義的key-value對羽历,待驗證的數(shù)據(jù)中不需要完全覆蓋。
>>> schema = Schema({1: 2, 3: 4})
>>> schema({3: 4})
{3: 4}
如果我們希望完全覆蓋淡喜,可以設置參數(shù)required
>>> schema = Schema({1: 2, 3: 4}, required=True)
>>> try:
... schema({3: 4})
... raise AssertionError('MultipleInvalid not raised')
... except MultipleInvalid as e:
... exc = e
>>> str(exc) == "required key not provided @ data[1]"
True
或者僅僅設置必須含有其中某一個鍵key
:
>>> schema = Schema({Required(1): 2, 3: 4})
>>> try:
... schema({3: 4})
... raise AssertionError('MultipleInvalid not raised')
... except MultipleInvalid as e:
... exc = e
>>> str(exc) == "required key not provided @ data[1]"
True
>>> schema({1: 2})
{1: 2}
或者僅僅對某一個鍵設置可選擇
屬性:
>>> from voluptuous import Optional
>>> schema = Schema({1: 2, Optional(3): 4}, required=True)
>>> try:
... schema({})
... raise AssertionError('MultipleInvalid not raised')
... except MultipleInvalid as e:
... exc = e
>>> str(exc) == "required key not provided @ data[1]"
True
>>> schema({1: 2})
{1: 2}
>>> try:
... schema({1: 2, 4: 5})
... raise AssertionError('MultipleInvalid not raised')
... except MultipleInvalid as e:
... exc = e
>>> str(exc) == "extra keys not allowed @ data[4]"
True
>>> schema({1: 2, 3: 4})
{1: 2, 3: 4}
上一篇:Python數(shù)據(jù)驗證庫(二)validator
http://www.reibang.com/p/eee56214af9c