JSONLINT:python的json数据验证库实例解析

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写。

JSON 函数

使用 JSON 函数需要导入 json 库:import json。

函数 描述
json.dumps 将 Python 对象编码成 JSON 字符串
json.loads 将已编码的 JSON 字符串解码为 Python 对象

随着前后端分离和 REST APIs 的火热,开发者不断寻找着一种灵活的、优雅的方式验证 json 数据。有直接手动获取数据验证的,也有使用 json scheme 验证的。前者容易使得函数变得冗长,还可能存在不少重复的验证;后者验证又不灵活。

本文介绍的 jsonlint 启发自 python 的表单验证工具 wtforms,wtforms 通过继承 Form 类也能进行 json 数据验证,但是 wtforms 对于 json 的数组(Array)类型处理有着很诡异的行为,需要通过 a-1 、 a-2 这样来传递数组数据,常常不能有效的处理数组数据。 jsonlint 大部分代码来着 wtforms,可以视为 wtforms 的一个分支。但 jsonlint 删去了 wtforms 的表单渲染部分,更改了传入的数据格式,最重要的是使用正确的逻辑验证数组(Array)和对象(Object)类型。下面是一些例子:

基本的字符串类型json验证

对于基本的字符串类型,我们只需要创建一个 Json 的子类,填写对应的 Field 即可。使用方式和 wtforms 类型:

from jsonlint import Json
from jsonlint.fields import StringField
from jsonlint.validators import DataRequired
class MyLint(Json):
 name = StringField(validators=[DataRequired()])
mylint = MyLint({'name': 'demo'})
print mylint.validate() # True
print mylint.name.data # demo

更灵活的验证 json 数据

jsonlint 继承了 wtforms 的优点,可以进行一些更灵活的自定义json数据验证,只要将 field 类的实例名写成函数 validate_fieldname ,即可自定义验证改字段:

from jsonlint import Json
from jsonlint.fields import IntegerField
from jsonlint.validators import ValidationError
class AgeLint(Json):
 age = IntegerField()
 def validate_age(form, field):
  if field.data < 13:
   raise ValidationError("We're sorry, you must be 13 or older to register")
agelint = AgeLint({'age': 12})
print agelint.validate() # False
print agelint.age.errors # ["We're sorry, you must be 13 or older to register"]

对数组类型进行验证

jsonlint 诞生可以说主要就是为了解决如何验证数组类型的问题,在jsonlint这很容易实现:

from jsonlint import Json
from jsonlint.fields import StringField, ListField
from jsonlint.validators import DataRequired, ValidationError
class ListLint(Json):
 cars = ListField(StringField(validators=[DataRequired()]))
 def validate_cars(form, field):
  if 'BMW' in field.data:
   raise ValidationError("We're sorry, you cannot drive BMW")
listlint = ListLint({'cars': ['Benz', 'BMW', 'Audi']})
print listlint.validate() # False
print listlint.cars.errors # ["We're sorry, you cannot drive BMW"]

ListField 类作为一个 Field 容器,容纳其它类型 Field 的数组,将对应类型的数组直接传入,即可有效的验证;ListField 同样也可以进行自定义验证。

对对象类型进行验证

对象类型在一些 REST APIs 的 web 应用中也经常存在,对此 jsonlint 也作了支持。只要将 Json 子类传入 ObjectField 中即可进行验证:

from jsonlint import Json
from jsonlint.fields import ObjectField, IntegerField, BooleanField
class T(Json):
 status = BooleanField()
 code = IntegerField()
class DataLint(Json):
 data = ObjectField(T)
datalint = DataLint({'data': {'status': True, 'code': 200}})
print datalint.validate() # False
print datalint.data.code.data # 200

写在最后

jsonlint 诞生初衷就是因为本人想用类似 wtforms 的方式来验证json,这样不但有着良好的验证方式,还可以分割业务,避免接口主函数变得十分冗长。例如,可以定义类:

class RegisterLint(UserLint):
 def validata_nickname(self, field):
  ...
 def validate_account(self, field):
  ...
 def create_user(self):
  ...
user = RegisterLint()

这样既可以使用 RegisterLint 的实例 user 验证数据,同时又能直接执行 user.create_user() 进行数据库操作,将数据库逻辑更好的封装。这样可以说是在 MVC 设计模式的基础上独立出了一层。

想要尝试使用 jsonlint 可以直接使用 pip 安装:

pip install jsonlint

最后,jsonlint 开源在 Github : https://github.com/tangwz/jsonlint

jsonlint 现阶段仅由我一人维护,虽然单元测试覆盖率尽可能的全覆盖,但也不代表没有bug,希望您提出您宝贵的意见,或一起维护、迭代jsonlint:

https://github.com/tangwz/jsonlint/issues

如果使用 Flask 进行 web 开发,也可以使用封装好的结合了 Flask 和 jsonlint 的库: Flask-Lint

(0)

相关推荐

  • python使用json序列化datetime类型实例解析

    使用python的json模块序列化时间或者其他不支持的类型时会抛异常,例如下面的代码: # -*- coding: cp936 -*- from datetime import datetime import json if __name__=='__main__': now = datetime.now() json.dumps({'now':now}) 运行会出现下面的错误信息: Traceback (most recent call last): File "C:\Users\xx\De

  • Python3.x对JSON的一些操作示例

    前言 本文主要给大家介绍了关于python3对JSON的一些操作,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一.Dictionary 转为JSON 将dict转为JSON,这里利用包json import json aItem = {} aItem["id"] = "2203" aItem["title"] = "title" aItem["subTitle"] = "su

  • Python Json序列化与反序列化的示例

    不同的编程语言有不同的数据类型; 比如说: Python的数据类型有(dict.list.string.int.float.long.bool.None) Java的数据类型有(bool.char.byte.short.int.long.float.double) C的数据类型有(bit.bool.char.int.short.long.unsigned.double.float) Tcl的数据类型(int.bool.float.string) Ruby的数据类型(Number.String.R

  • python 读写中文json的实例详解

     python 读写中文json的实例详解 读写中文json 想要 读写中文json ,可以使用python中的 json 库可以对json进行操作.读入数据可以使用 json.load. f = file(path) data = json.load(f) json被载入到一个dict类型的object对象中. 使用 json.dump可以输出json.不过输出的文本并不是中文,而是转换为 utf-8的格式.此处需要: output = json.dump(jsonData,targetFil

  • Python读取Json字典写入Excel表格的方法

    需求: 因需要将一json文件中大量的信息填入一固定格式的Excel表格,单纯的复制粘贴肯定也能完成,但是想偷懒一下,于是借助Python解决问题. 环境: Windows7 +Python2.7 +Xlwt 具体分析: 原始文件为json列表,列表中有多个字典,生成Excel文件需要将列表中的字典的键值按键对应排列,也就是说,所有为"XX"的键对应的值写在一列,且每个字典中的不同键的键值保证在同一行. 解决思路是,读取json文件,然后遍历字典的键和值,读完第一个字典并写入Excel

  • Python3 处理JSON的实例详解

    Python3 处理JSON的实例详解 真的好简单,灰常简单 import os, io, sys, re, time, base64, json import webbrowser, urllib.request def main(): "main function" url = "http://m.weather.com.cn/data/101010100.html" stdout=urllib.request.urlopen(url) weatherInfo=

  • python数据封装json格式数据

    最简单的使用方法是: >>> import simplejson as json >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]' >>> print(json.dumps("\"foo\bar")) "\&q

  • python 3.6 tkinter+urllib+json实现火车车次信息查询功能

    一.概述 妹子工作时需要大量地查询火车车次至南京的信息,包括该车次到达站(南京站or南京南站).到达时间.出发时间等,然后根据这些信息做下一步工作. 版本结束,趁着间歇期,帮她弄了个简易的批量查询工具,粉色的按钮是给她用的~哈哈哈! (๑*◡*๑) 大概80行代码,主要是: 界面读取待查询车次 - - - - 调用车次信息接口- - - - 解析返回数据 - - - - 组装结果 - - - - 封装到界面(tkinter) python+tkinter实现界面,详见之前的学习笔记:http:/

  • Python实现JSON反序列化类对象的示例

    我们的网络协议一般是把数据转换成JSON之后再传输.之前在Java里面,实现序列化和反序列化,不管是 jackson ,还是 fastjson 都非常的简单.现在有项目需要用Python来开发,很自然的希望这样的便利也能在Python中体现. 但是在网上看了一些教程,讲反序列化的时候,基本都是转换为 dict 或者 array .这种编程方式我从情感上是无法接受的.难道是这些JSON库都不支持反序列化为类对象?我马上打消了这个念头,Python这样强大的脚本语言,不可能没有完善的JSON库. 于

  • python判断字符串是否是json格式方法分享

    在实际工作中,有时候需要对判断字符串是否为合法的json格式 解决方法使用json.loads,这样更加符合'Pythonic'写法 代码示例: Python import json def is_json(myjson): try: json_object = json.loads(myjson) except ValueError, e: return False return True 运行代码编辑模式复制折叠 输出结果: Python print is_json("{}") #

  • Python实现读取json文件到excel表

    本文实例为大家分享了Python实现读取json文件到excel表,供大家参考,具体内容如下 一.需求 1.'score.json' 文件内容: { "1":["小花",99,100,98.5], "2":["小王",90,30.5,95], "3":["小明",67.5,49.6,88] } 2.读取json文件保存到数据库,并计算出每个人的总分和平均分 二.实现代码 import j

  • Python简单读取json文件功能示例

    本文实例讲述了Python简单读取json文件功能.分享给大家供大家参考,具体如下: read_json.json: { "rule":{ "namespace":"strategy", "name":"test_exp_1496234234223400", "version":0, "last_modify_time":1434234236819000, "

随机推荐