天天看點

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資料

共勉: 東漢·班固《漢書·枚乘傳》:“泰山之管穿石,單極之绠斷幹。水非石之鑽,索非木之鋸,漸靡使之然也。”

-----指水滴不斷地滴,可以滴穿石頭;

-----比喻堅持不懈,集細微的力量也能成就難能的功勞。