Python-schema的使用

有一种方式比较优雅的验证用户数据 - schema 



安装

pip install schema


Schema

基本类型:满足条件后会返回当前的值,不满足将报错!


from schema import Schema
print Schema(int).validate(10)      # 10
print Schema(int).validate('10')    # schema.SchemaUnexpectedTypeError


list/tuple/set:只需满足list/tuple/set中的其中一个条件后会返回当前的值,不满足将报错!!


from schema import Schema
print Schema([int, float]).validate([1, 2, 3, 3.3])             # [1, 2, 3, 3.3]
print Schema([int, float]).validate([1, 2, 3, 4])               # [1, 2, 3, 4]
print Schema([int, float]).validate(['a', 'b', 'c', 'd'])       # schema.SchemaError


字典:首先,模型字典与数据字典的Key是否完全一样,不一样将报错;而后,那数据字典的value验证模型字典相应的value,如果验证通过才会返回数据,否则将会报错


from schema import Schema
print Schema({"name": str, "age": int}).validate({"name": "laozhang", "age": 18})           # {'age': 18, 'name': 'laozhang'}
print Schema({"name": str, "age": int}).validate({"name": "laozhang"})                      # schema.SchemaMissingKeyError
print Schema({"name": str, "age": int}).validate({"name": 18, "age": 18})                   # schema.SchemaError
print Schema({"name": str, "age": int}).validate({"name": 18, "age": 18, "addr": "广东"})   # schema.SchemaWrongKeyError


有个概念值得注意:Schema传入的字典,我们通常称之为模型字典,validate传入的字典,我们通常称之为数据字典


可调用的对象:满足可调用的对象的条件后会返回当前的值,不满足将报错!


from schema import Schema
print Schema(lambda x: 1 < x < 8).validate(5)       # 5
print Schema(lambda x: 1 < x < 8).validate(8)       # schema.SchemaError


Use

Use在验证的时候,会自动帮你转换它的值


from schema import Schema, Use
print Schema(Use(int)).validate(10)                 # 10-->int类型
print Schema(Use(int)).validate('10')               # 10-->int类型
print Schema(Use(int)).validate('xiaoming')         # schema.SchemaError

Const

我们知道Use在验证的时候,会自动帮你转换它的值。Const可以保持原始数据不变:


from schema import Schema, Use, Const
print Schema(Const(Use(int))).validate('10')        # 10-->str类型


And

And对是否满足多个条件进行验证


from schema import Schema, And
print Schema(And(int, lambda x: x < x < 8)).validate(5)             # 5
print Schema(And(int, lambda x: x < x < 8)).validate(8)             # schema.SchemaError
print Schema(And(int, lambda x: x < x < 8)).validate('5')           # schema.SchemaError

Or

Or对是否满足其中一个条件进行验证


from schema import Schema, Or, Use
print Schema(Or(lambda x: 1 < x < 8, Use(int))).validate(5)                 # 5-->int类型
print Schema(Or(lambda x: 1 < x < 8, Use(int))).validate(8)                 # 8-->int类型
print Schema(Or(lambda x: 1 < x < 8, Use(int))).validate('8')               # 8-->int类型
print Schema(Or(lambda x: 1 < x < 8, Use(int))).validate('xiaoming')        # schema.SchemaError


Optional

Schema传入字典进行验证很好用,可是常常因为传入的字典与模型字典key不匹配,从而导致报错,此时我们可以使用Optional进行可选验证字典:


from schema import Schema, Optional
print Schema({"name": str, Optional("age"): int}).validate({"name": "laozhang"})                                # {'name': 'laozhang'}
print Schema({"name": str, Optional("age"): int}).validate({"name": "laozhang", "age": 18})                     # {'age': 18, 'name': 'laozhang'}
print Schema({"name": str, Optional("age"): int}).validate({"name": 18, "age": 18})                             # schema.SchemaError
print Schema({"name": str, Optional("age"): int}).validate({"name": "laozhang", "age": 18, "addr": "广东"})     # schema.SchemaWrongKeyError


我们还可以在Optional中设置一个默认值,如下:

print Schema({"name": str, Optional("age", default=18): int}).validate({"name": "laozhang"})                    # {'age': 18, 'name': 'laozhang'}


上面这种方式只是用于数据字典的key比模型字典的key少的情况,如果数据字典的key比模型字典的多,那么又该如何进行忽略验证呢?我们可以使用ignore_extra_keys参数,并将其设置为True,如下:


from schema import Schema
print Schema({"name": str, "age": int}, ignore_extra_keys=True).validate({"name": "laozhang", "age": 18, "addr": "广东"})       # {'age': 18, 'name': 'laozhang'}


Forbidden

Forbidden可以将某个key禁止:


from schema import Schema, Forbidden
print Schema({Forbidden('name'): str, 'age': int}).validate({"age": 15})                            # {"age": 15}
print Schema({Forbidden('name'): str, 'age': int}).validate({"name": "laozhang", "age": 15})        # schema.SchemaForbiddenKeyError
print Schema({Forbidden('name'): str, 'age': int}).validate({"name": 10, "age": 15})                # schema.SchemaWrongKeyError


值得注意的是,与禁用秘钥配对的值将决定了它是否会被拒绝:


from schema import Schema, Forbidden
print Schema({Forbidden('name'): int, 'name': str}).validate({'name': 'laozhang'})                  # {'name': 'laozhang'}
print Schema({Forbidden('name'): str, 'name': str}).validate({'name': 'laozhang'})                  # schema.SchemaForbiddenKeyError


另外,Forbidden的优先级要比Optional要高:


from schema import Schema, Forbidden, Optional
print Schema({Forbidden('name'): str, Optional('name'): str}).validate({"name": "laozhang"})        # schema.SchemaForbiddenKeyError


Regex

Regex可以根据正则表达式进行匹配验证


import re
from schema import Regex
print Regex('^foo').validate('football')        # football
print Regex('^foo').validate('basketball')      # schema.SchemaError


# flags=re.I忽略大小写

print Regex('[A-Z]+', flags=re.I).validate('football')      # football


当然,Regex同样也可以配合Schema一起使用:


from schema import Schema, Regex


print Schema(Regex('^foo')).validate('football')            # football


自定义错误

Schema、And、Or、Use等类都有一个参数error,可以自定义错误信息:


from schema import Schema


print Schema(int, error='只能是整数类型').validate('abc')      # schema.SchemaUnexpectedTypeError: 只能是整数类型

————————————————

转载:https://blog.csdn.net/y472360651/article/details/81949653