天天看点

python使用外部库demjson转换json数据

作者:科雷软件测试

学习目录

外部库demjson库介绍

为什么使用demjson

通过import demjson导入demjson库,提供了2个常用的函数

demjson.decode()

demjson.encode()

demjson自带jsonlint工具,用来校验json文件的准确性

python使用外部库demjson转换json数据

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,目前被广泛应用,在实际使用过程中不管是开发工程师还是测试工程师都必须学会json数据的处理。

Python中有几个库可以比较好的处理json数据,比如内置库json、外部库Demjson、jsonpath,本章主要介绍外部库Demjson使用

外部库Demjson库

安装

通过pip install Demjson 安装,但因为不同python版本问题,有可能会报错如下:

python使用外部库demjson转换json数据

虽然demjson 2.2.4版本兼容了python2和python3,但是安装环境python3时,有一部分代码需要做转换,而setuptools从版本58.0.0开始不再支持2to3的builds,所以导致 demjson 2.2.4安装后报错。

通过降低setuptools版本即可解决,比如pip install steuptools==57.5.0安装低版本,然后在执行安装Demjson。

python使用外部库demjson转换json数据

为什么使用demjson

demjson的一些优点:

它适用于没有内置JSON的旧Python版本;

它通常具有更好的错误处理和“lint”检查功能;

每当可能出现溢出或精度损失时,它将自动使用Python Decimal(bigfoat)类,而不是浮点数。

它可以正确处理不同的Unicode编码,包括ASCII。它将根据编码自动调整何时使用转义符。

它生成更保守的JSON,例如转义Unicode格式的控制字符或行终止符,这将提高数据的可移植性。

在非严格模式下,它还可以处理稍微不一致的输入,这些输入更多的是JavaScript而不是JSON(例如允许注释)。

在转换过程中,它支持更广泛的Python类型集。

通过import demjson导入demjson库,提供了2个常用的函数

函数 描述
demjson.encode() 将Python对象编码成 JSON字符串
demjson.decode() 将已编码的 JSON 字符串解码为Python对象

demjson.encode()使用

1 定义一个字典

dict_data = {"name":"userinfo",
"province":"js",
"users":[
{u"name":"王磊","age":21,"address":["nj","jiangningqu","xixihuayuan"]},
{u"name":"莉莉","age":20,"address":["yz","qixiaqu","qinqinhuayuan"]},
{u"name":"娜娜","age":21,"address":["sz","yuhuataiqu","huiyuhuayuan"]}
]
}           

2 使用demjson.encode转换为json数据

print(demjson.encode(dict_data))

#结果如下:
{"name":"userinfo","province":"js",
"users":[{"address":["nj","jiangningqu","xixihuayuan"],"age":21,"name":"\u738b\u78ca"},
         {"address":["yz","qixiaqu","qinqinhuayuan"],"age":20,"name":"\u8389\u8389"},
         {"address":["sz","yuhuataiqu","huiyuhuayuan"],"age":21,"name":"\u5a1c\u5a1c"}]}           

以上结果有两个问题:

1) name为中文的打印为unicode编码

2) 打印的json数据不美观

而函数中有几个参数可以辅助解决以上问题

1) 参数增加 compactly=False,indent_amount=4

参数compactly”默认设置为True,则生成的字符串将

去除所有多余的空格;如果为False,则字符串将用空白和

添加缩进(配合indent_amount缩进参数)使其可读性更强。

print(demjson.encode(dict_data,compactly=False,indent_amount=4))
{
    "name" : "userinfo",
    "province" : "js",
    "users" : [
               {
                "address" : [
                               "nj",
                               "jiangningqu",
                               "xixihuayuan"
                            ],
                "age" : 21,
                "name" : "\u738b\u78ca"
								...此处省略
               }
              ]
}           
python使用外部库demjson转换json数据

2 增加encoding='utf8'参数

encoding默认为None*,表示返回的是一个Unicode字符串。

*encoding可以传入编码方式,如“UTF-8”或“ascii”。

如果给定了编码,则返回的json是“bytes”字节码(Python 3)或“str”字符串(Python 2)。

我的电脑是python3,所以带上encoding='utf8'参数后,打印结果为字节码(前面带了字母b)

print(demjson.encode(dict_data,encoding='utf8'))

b'{"name":"userinfo","province":"js","users":[{"address":["nj","jiangningqu","xixihuayuan"],"age":21,"name":"\xe7\x8e\x8b\xe7\xa3\x8a"},
{"address":["yz","qixiaqu","qinqinhuayuan"],"age":20,"name":"\xe8\x8e\x89\xe8\x8e\x89"},
{"address":["sz","yuhuataiqu","huiyuhuayuan"],"age":21,"name":"\xe5\xa8\x9c\xe5\xa8\x9c"}]}'
           

通过字节码的decode()函数可以解码为中文

print(demjson.encode(dict_data,encoding='utf8').decode())
{"name":"userinfo","province":"js","users":[{"address":["nj","jiangningqu","xixihuayuan"],"age":21,"name":"王磊"},
{"address":["yz","qixiaqu","qinqinhuayuan"],"age":20,"name":"莉莉"},
{"address":["sz","yuhuataiqu","huiyuhuayuan"],"age":21,"name":"娜娜"}]}           

支持原字典中Decimal对象,datetime对象等

from decimal import Decimal
import datetime
import json
dict_data = {"name":"lili","age":Decimal(str('20.0')),
             "datetime":datetime.datetime.now()
             }           
使用json.dumps()执行会报错
print(json.dumps(dict_data))
#结果如下
TypeError: Object of type Decimal is not JSON serializable           
使用demjson.encode()转换成功
print(demjson.encode(dict_data))
#结果如下
{"age":20.0,"datetime":"2023-08-06T20:53:05.538254","name":"lili"}
           

demjson.decode()使用

1 定义json数据

json_data= ‘{"age":20.0,"datetime":"2023-08-06T20:55:46.728625","name":"lili"}’
print(demjson.decode(json_data))           

2 使用demjson.decode()将json数据转为字典,类似于json.loads()

print(demjson.decode(json_data))
#结果如下
{'age': 20.0, 'datetime': '2023-08-06T20:55:46.728625', 'name': 'lili'}           

demjson自带jsonlint工具,用来校验json文件的准确性

本地创建一个test.json文件,文件中有一处错误,使用jsonlint校验,结果如下:

(venv) htsc@192 bin % jsonlint test.json
test.json:1:18: Error: Values must be separated by a comma
   |  At line 1, column 18, offset 18
   |  Object started at line 1, column 0, offset 0 (AT-START)
test.json: has errors           
python使用外部库demjson转换json数据

共勉: 东汉·班固《汉书·枚乘传》:“泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。”

-----指水滴不断地滴,可以滴穿石头;

-----比喻坚持不懈,集细微的力量也能成就难能的功劳。