资讯专栏INFORMATION COLUMN

Python Schema一种优雅的数据验证方式

lijy91 / 2812人阅读

摘要:意味着我们要对用户输入进行严格的验证,开发时一般输入数据都以形式发送到后端,要对输入数据做验证。一般我都是加很多判断,各种,导致代码很丑陋,能不能有一种方式比较优雅的验证用户数据呢就派上用场了。

Python Schema使用说明

项目地址:GitHub

Schema是什么?

不管我们做什么应用,只要和用户输入打交道,就有一个原则--永远不要相信用户的输入数据。意味着我们要对用户输入进行严格的验证,web开发时一般输入数据都以JSON形式发送到后端API,API要对输入数据做验证。一般我都是加很多判断,各种if,导致代码很丑陋,能不能有一种方式比较优雅的验证用户数据呢?Schema就派上用场了。

Schema非常简单,也就几百行的代码,最核心的类就一个:Schema

1. 给Schema类传入类型(intstrfloat等)

例如:

from schema import Schema

Schema(int).validate(10)
10
Schema(int).validate("10")
SchemaUnexpectedTypeError: "10" should be instance of "int"

可见Schema会去验证validate方法传入的对象是不是所指定的类型,是则返回传入的数据,否则抛出一个SchemaError的异常(SchemaUnexpectedTypeErrorSchemaError的子类)。

2. 给Schema类传入可调用的对象(函数、带__call__的类等)

例如:

Schema(lambda x: 0(57) should evaluate to True

可见Schema会把validate方法传入的值传入到对应的函数里面作为参数,如果函数返回值为True则返回输入数据,否则抛出异常。

3. 给Schema类传入带有validate方法的对象

Schema也内置了一些类(UseAndOr等等),这些类的实例都带有validate方法,亦可作为Schema的参数传入,例如:

from schema import Schema, And

# And代表两个条件必须同时满足
Schema(And(str, lambda s: len(s) > 2)).validate("abcd")
"abcd"
4. 给Schema类传入容器对象(listtupleset等)

例如:

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: Missing keys: "age"

首先,明确两个概念,Schema类传入的字典,称之为模式字典valdiate方法传入的字典称之为数据字典

首先,Schema会判断, 模式字典和数据字典的key是否完全一样,不一样的话直接抛出异常。如果一样,就去拿数据字典的value去验证模式字典相应的value,如果数据字典的全部value都可以验证通过的话才返回数据,否则抛出异常,是不是感觉这种验证顿时感觉清爽了呢?

6. faqs

Schema传入字典很好用,但是我有的数据是可选的,也就是说有的key可以不提供怎么办?

from schema import Optional, 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自带的类(UseAndOrRegexSchema等)都有一个参数error,可以自定义错误信息

Schema({"name": str, "age": Use(int, error="年龄必须是整数")}).validate({"name": "foobar", "age": "abc"})
SchemaError: 年龄必须是整数

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/40971.html

相关文章

  • 自动化代码生成工具 Snips 开发实践

    摘要:今天我来和大家分享一下以及自动化生成工具的开发经验。代码生成工具接着讲讲代码生成工具,对于来讲,有官方的代码生成器,还有其他的同类开源项目比如。现有的代码生成器没有可以开箱即用的,都需要去进行不少的修改。 前言 在开发工作中,经常会遇到新产品、服务上线后,需要将其 API 编写不同语言的 SDK。但不同语言 SDK 中都有很大一部分内容是用来进行 API 的描述,而且这部分代码量是最大...

    only_do 评论0 收藏0
  • 自动化代码生成工具 Snips 开发实践

    摘要:今天我来和大家分享一下以及自动化生成工具的开发经验。代码生成工具接着讲讲代码生成工具,对于来讲,有官方的代码生成器,还有其他的同类开源项目比如。现有的代码生成器没有可以开箱即用的,都需要去进行不少的修改。 前言 在开发工作中,经常会遇到新产品、服务上线后,需要将其 API 编写不同语言的 SDK。但不同语言 SDK 中都有很大一部分内容是用来进行 API 的描述,而且这部分代码量是最大...

    qc1iu 评论0 收藏0
  • 自动化代码生成工具 Snips 开发实践

    摘要:今天我来和大家分享一下以及自动化生成工具的开发经验。代码生成工具接着讲讲代码生成工具,对于来讲,有官方的代码生成器,还有其他的同类开源项目比如。现有的代码生成器没有可以开箱即用的,都需要去进行不少的修改。 前言 在开发工作中,经常会遇到新产品、服务上线后,需要将其 API 编写不同语言的 SDK。但不同语言 SDK 中都有很大一部分内容是用来进行 API 的描述,而且这部分代码量是最大...

    pepperwang 评论0 收藏0
  • 做好自动化 API 测试(1)- 从一个好用 Json Validator 开始

    摘要:就目前我的面试经验而言,绝大部分项目都没有引入自动化测试,测试基本都是依靠开发人员的自测以及测试人员黑盒测试。本文不探讨黑盒测试,仅仅发表一点我对自动化测试的想法。缘起早在两年多以前,就在思考如何做的测试,保证返回的结果与预期的一致。 目前,前后端分离的开发模式越来越受到大家的青睐,前端与后端的职责也更加清晰,后端通过 API 提供数据,前端通过 API 获取数据,展示页面,前端有更大...

    RancherLabs 评论0 收藏0
  • marshmallow快速上手

    摘要:方法对应的是方法,它反序列化一个字典为数据结构。某些例如和内置了验证器验证集合时,错误字典将基于无效字段的索引作为键通过给的参数传递对象,可以执行额外的验证验证函数可以返回布尔值或抛出异常。 快速上手 Declaring Schemas 首先创建一个基础的user模型(只是为了演示,并不是真正的模型): import datetime as dt class User(object)...

    jhhfft 评论0 收藏0

发表评论

0条评论

lijy91

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<