python進(jìn)階之JSON數(shù)據(jù)解析完整示例
引言
在當(dāng)今數(shù)據(jù)驅(qū)動(dòng)的世界中,JSON已成為數(shù)據(jù)交換的事實(shí)標(biāo)準(zhǔn)。無(wú)論是與 Web API 交互、配置應(yīng)用程序、存儲(chǔ)結(jié)構(gòu)化數(shù)據(jù),還是處理來(lái)自物聯(lián)網(wǎng)設(shè)備的數(shù)據(jù),幾乎不可避免地會(huì)遇到 JSON 格式。
一、JSON簡(jiǎn)介
JSON(JavaScript Object Notation)是一種輕量級(jí)的、基于文本的數(shù)據(jù)交換格式。它被設(shè)計(jì)為易于人閱讀和編寫(xiě),同時(shí)也易于機(jī)器解析和生成,被廣泛應(yīng)用于各種編程語(yǔ)言和平臺(tái)之間。
JSON 數(shù)據(jù)由鍵值對(duì)組成,支持以下幾種基本數(shù)據(jù)類(lèi)型:
- 對(duì)象 (Object): 用花括號(hào)
{}包圍,包含零個(gè)或多個(gè)鍵值對(duì),鍵是字符串,值可以是任何有效的 JSON 數(shù)據(jù)類(lèi)型。 - 數(shù)組 (Array): 用方括號(hào)
[]包圍,包含零個(gè)或多個(gè)值,值之間用逗號(hào)分隔。 - 字符串 (String): 用雙引號(hào)
""包圍的字符序列。 - 數(shù)字 (Number): 整數(shù)或浮點(diǎn)數(shù)。
- 布爾值 (Boolean):
true或false - 空值 (Null):
null
例如:
people.json文件:
[
{
"name": "張三",
"gender": "男",
"age": 25
},
{
"name": "李四",
"gender": "女",
"age": 23
}
]二、python中JSON模塊
Python 的 JSON模塊是處理 JSON 數(shù)據(jù)的標(biāo)準(zhǔn)工具。它提供了四個(gè)核心函數(shù)用于在 JSON 字符串/文件和 Python 對(duì)象之間進(jìn)行轉(zhuǎn)換:
2.1 json.load()
從 JSON文件對(duì)象讀取并解析為Python 對(duì)象。
json.load(fp, *, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
- 參數(shù):
fp: 一個(gè)支持.read()方法的文本文件對(duì)象,數(shù)據(jù)從這個(gè)文件對(duì)象中讀取。cls(可選): 用于自定義 JSON 解碼器的類(lèi)。通常用于處理復(fù)雜的對(duì)象。object_hook(可選): 一個(gè)函數(shù),用于在解碼每個(gè) JSON 對(duì)象后進(jìn)行自定義處理。它接收一個(gè)字典作為參數(shù),并應(yīng)返回一個(gè)對(duì)象(通常是字典或自定義對(duì)象)。parse_float(可選): 一個(gè)函數(shù),用于將 JSON 中的浮點(diǎn)數(shù)字符串轉(zhuǎn)換為 Python 對(duì)象。默認(rèn)是float。parse_int(可選): 一個(gè)函數(shù),用于將 JSON 中的整數(shù)字符串轉(zhuǎn)換為 Python 對(duì)象。parse_constant(可選): 一個(gè)函數(shù),用于處理 JSON 常量 ('-Infinity','Infinity','NaN')。object_pairs_hook(可選): 一個(gè)函數(shù),接收一個(gè)由(key, value)對(duì)組成的列表,并返回一個(gè)對(duì)象。object_pairs_hook優(yōu)先于object_hook。**kw(可選): 其他關(guān)鍵字參數(shù)。- 返回值: 一個(gè) Python 對(duì)象(通常是
dict或list)。
2.2 json.loads()
從JSON 字符串(str)讀取并解析為 Python 對(duì)象。
json.loads(s, *, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)參數(shù)同
json.dump。
2.3 json.load()
將 Python 對(duì)象 編碼為 JSON格式寫(xiě)入文件。
json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True,
check_circular=True, allow_nan=True, cls=None, indent=None,
separators=None, default=None, sort_keys=False, **kw)
- 參數(shù):
obj: 一個(gè)必需的參數(shù)。要序列化的 Python 對(duì)象。它必須是dict,list,tuple,str,int,float,bool,None,或者是一個(gè)實(shí)現(xiàn)了__json__()方法的對(duì)象。fp: 一個(gè)必需的參數(shù)。一個(gè)支持.write()方法的文本文件對(duì)象(通常由open()函數(shù)返回,模式為'w'或'a')。JSON 數(shù)據(jù)將寫(xiě)入這個(gè)文件對(duì)象。skipkeys(可選): 如果為True,當(dāng)字典的鍵不是基本類(lèi)型(str,int,float,bool,None)時(shí),會(huì)自動(dòng)跳過(guò)該鍵值對(duì),而不是引發(fā)TypeError。ensure_ascii(可選): 如果為True,輸出將確保所有非 ASCII 字符都被轉(zhuǎn)義。如果為False,則允許直接輸出這些字符(通常用于生成人類(lèi)可讀的文件)。check_circular(可選): 如果為True,會(huì)檢查容器類(lèi)型的循環(huán)引用(如列表包含自身),如果發(fā)現(xiàn)則引發(fā)ValueError。如果為False,則不檢查,但遇到循環(huán)引用時(shí)行為未定義。allow_nan(可選): 如果為True,允許float類(lèi)型的NaN,Infinity,-Infinity。如果為False,則在序列化這些值時(shí)會(huì)引發(fā)ValueError。cls(可選): 用于自定義 JSON 編碼器的類(lèi)。indent(可選): 用于美化輸出。如果是一個(gè)非負(fù)整數(shù)或字符串(如'\t'),則 JSON 數(shù)組元素和對(duì)象成員將被換行并使用該值進(jìn)行縮進(jìn),使其更易讀。None(默認(rèn))表示單行輸出。separators(可選): 一個(gè)(item_separator, key_separator)元組。默認(rèn)是(', ', ': ')??梢栽O(shè)置為(',', ':')以減少輸出大?。ㄈコ崭瘢?。default(可選): 一個(gè)函數(shù),用于處理json模塊無(wú)法序列化的對(duì)象。該函數(shù)應(yīng)返回一個(gè)可序列化的對(duì)象,或者引發(fā)TypeError。sort_keys(可選): 如果為True,則字典的輸出將按鍵的字符串表示進(jìn)行排序。**kw(可選): 其他關(guān)鍵字參數(shù)。- 返回值: 無(wú) (
None)。
2.4 json.dumps()
將 Python 對(duì)象 編碼為 JSON 字符串(str)。
json.dumps(obj, *, skipkeys=False, ensure_ascii=True,
check_circular=True, allow_nan=True, cls=None, indent=None,
separators=None, default=None, sort_keys=False, **kw)參數(shù)同
json.dump。
三、數(shù)據(jù)格式轉(zhuǎn)換規(guī)則
Python 對(duì)象與 JSON 值之間的轉(zhuǎn)換規(guī)則是數(shù)據(jù)處理的關(guān)鍵。
JSON | Python |
|---|---|
object | dict |
array | list |
string | str |
number (int) | int |
number (real) | float |
true | True |
false | False |
null | None |
注意:
- JSON 的
null對(duì)應(yīng) Python 的None。 - JSON 的
true/false對(duì)應(yīng) Python 的True/False。
四、異常處理
JSONDecodeError 是 ValueError 的一個(gè)子類(lèi),提供了更豐富的錯(cuò)誤信息,當(dāng)解析 JSON 文檔時(shí)發(fā)生錯(cuò)誤(即 JSON 格式不正確)時(shí)會(huì)引發(fā)此異常,這對(duì)于調(diào)試 JSON 格式問(wèn)題非常有幫助。
(該異常在 Python 3.5 版本中添加)
exception json.JSONDecodeError(msg, doc, pos)
額外的屬性:
msg: 未格式化的錯(cuò)誤消息(即描述錯(cuò)誤原因的文本)。doc: 正在被解析的原始 JSON 文檔(字符串)。pos: 在doc字符串中,解析失敗開(kāi)始的索引位置(從 0 開(kāi)始的字符位置)。lineno: 與pos位置對(duì)應(yīng)的行號(hào)(從 1 開(kāi)始計(jì)數(shù))。colno: 與pos位置對(duì)應(yīng)的列號(hào)(從 1 開(kāi)始計(jì)數(shù))。
示例:
新建一個(gè)bad.json文件:
{
"name": "Alice",
"age": 30, // 這里多了一個(gè)逗號(hào)
}嘗試解析它:
import json
try:
with open('bad.json', 'r') as file:
data = json.load(file)
except json.JSONDecodeError as e:
print(f"錯(cuò)誤消息: {e.msg}")
print(f"錯(cuò)誤位置: 第 {e.lineno} 行, 第 {e.colno} 列")
print(f"錯(cuò)誤索引: {e.pos}")
# 如果需要,可以打印整個(gè)文檔或相關(guān)部分
# print(f"文檔: {e.doc}")可能的輸出:
錯(cuò)誤消息: Expecting property name enclosed in double quotes 錯(cuò)誤位置: 第 3 行, 第 2 列 錯(cuò)誤索引: 35
五、完整示例
解析第一章節(jié)中的people.json文件:
import json
# 1. 定義文件名
filename = 'people.json'
try:
# 2. 打開(kāi)文件并讀取
with open(filename, 'r', encoding='utf-8') as file:
# 3. 使用 json.load() 解析文件內(nèi)容
data = json.load(file)
# 4. 打印解析結(jié)果,驗(yàn)證數(shù)據(jù)類(lèi)型和內(nèi)容
print("=== 解析結(jié)果 ===")
print("原始數(shù)據(jù)類(lèi)型:", type(data)) # <class 'list'>
print("解析后的數(shù)據(jù) (Python 列表):")
print(data)
print("\n")
# 5. 訪(fǎng)問(wèn)和使用數(shù)據(jù)
print("=== 信息 ===")
for person in data:
print(f"{person['name']} - {person['gender']}, {person['age']}歲")
except FileNotFoundError:
print(f"錯(cuò)誤:找不到文件 '{filename}'。")
print("請(qǐng)確保 'people.json' 文件存在于當(dāng)前目錄,或者檢查文件名是否正確。")
except Exception as e:
print(f"發(fā)生未知錯(cuò)誤: {e}")結(jié)果:
=== 解析結(jié)果 ===
原始數(shù)據(jù)類(lèi)型: <class 'list'>
解析后的數(shù)據(jù) (Python 列表):
[{'name': '張三', 'gender': '男', 'age': 25}, {'name': '李四', 'gender': '女', 'age': 23}]
=== 信息 ===
張三 - 男, 25歲
李四 - 女, 23歲參考
到此這篇關(guān)于python進(jìn)階之JSON數(shù)據(jù)解析的文章就介紹到這了,更多相關(guān)python JSON數(shù)據(jù)解析內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python 實(shí)現(xiàn)定積分與二重定積分的操作
這篇文章主要介紹了Python 實(shí)現(xiàn)定積分與二重定積分的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05
Python第三方庫(kù)face_recognition在windows上的安裝過(guò)程
今天為大家介紹下face recognition在Windows系統(tǒng)上安裝與使用,但在Windows平臺(tái)上face recognition性能會(huì)有所下降2019-05-05
python實(shí)現(xiàn)掃描日志關(guān)鍵字的示例
下面小編就為大家分享一篇python實(shí)現(xiàn)掃描日志關(guān)鍵字的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
python原類(lèi)、類(lèi)的創(chuàng)建過(guò)程與方法詳解
在本篇文章里小編給各位分享了關(guān)于python原類(lèi)、類(lèi)的創(chuàng)建過(guò)程與方法的相關(guān)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們跟著學(xué)習(xí)參考下。2019-07-07
Python通過(guò)Schema實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證方式
這篇文章主要介紹了Python通過(guò)Schema實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
完美解決Python matplotlib繪圖時(shí)漢字顯示不正常的問(wèn)題
今天小編就為大家分享一篇完美解決Python matplotlib繪圖時(shí)漢字顯示不正常的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
Python對(duì)FTP交互封裝的實(shí)現(xiàn)
本文主要介紹了Python對(duì)FTP交互封裝的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06

