Python通过Schema实现数据验证方式
Schema是什么?
不管我们做什么应用,只要和用户输入打交道,就有一个原则--永远不要相信用户的输入数据。意味着我们要对用户输入进行严格的验证,web开发时一般输入数据都以JSON形式发送到后端API,API要对输入数据做验证。一般我都是加很多判断,各种if,导致代码很丑陋,能不能有一种方式比较优雅的验证用户数据呢?Schema就派上用场了。
Schema非常简单,也就几百行的代码,最核心的类就一个:Schema。
1.给Schema类传入类型(int、str、float等)
例如:
fromschemaimportSchema
Schema(int).validate(10)
10
Schema(int).validate('10')
SchemaUnexpectedTypeError:'10'shouldbeinstanceof'int'
可见Schema会去验证validate方法传入的对象是不是所指定的类型,是则返回传入的数据,否则抛出一个SchemaError的异常(SchemaUnexpectedTypeError是SchemaError的子类)。
2.给Schema类传入可调用的对象(函数、带__call__的类等)
例如:
Schema(lambdax:0
5
Schema(lambdax:0SchemaError: (57)shouldevaluatetoTrue
可见Schema会把validate方法传入的值传入到对应的函数里面作为参数,如果函数返回值为True则返回输入数据,否则抛出异常。
3.给Schema类传入带有validate方法的对象
Schema也内置了一些类(Use、And、Or等等),这些类的实例都带有validate方法,亦可作为Schema的参数传入,例如:
fromschemaimportSchema,And
#And代表两个条件必须同时满足
Schema(And(str,lambdas: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:Missingkeys:'age'
首先,明确两个概念,Schema类传入的字典,称之为模式字典,valdiate方法传入的字典称之为数据字典。
首先,Schema会判断,模式字典和数据字典的key是否完全一样,不一样的话直接抛出异常。如果一样,就去拿数据字典的value去验证模式字典相应的value,如果数据字典的全部value都可以验证通过的话才返回数据,否则抛出异常,是不是感觉这种验证顿时感觉清爽了呢?
6.faqs
Schema传入字典很好用,但是我有的数据是可选的,也就是说有的key可以不提供怎么办?
fromschemaimportOptional,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:年龄必须是整数
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。