目錄
引言
一、JSON簡介
二、python中JSON模塊
2.1 json.load()
2.2 json.loads()
2.3 json.load()
2.4 json.dumps()
三、數據格式轉換規則
四、異常處理
五、完整示例
參考
引言
在當今數據驅動的世界中,JSON已成為數據交換的事實標準。無論是與 Web API 交互、配置應用程序、存儲結構化數據,還是處理來自物聯網設備的數據,幾乎不可避免地會遇到 JSON 格式。
一、JSON簡介
JSON(JavaScript Object Notation)是一種輕量級的、基於文本的數據交換格式。它被設計為易於人閲讀和編寫,同時也易於機器解析和生成,被廣泛應用於各種編程語言和平台之間。
JSON 數據由鍵值對組成,支持以下幾種基本數據類型:
- 對象 (Object): 用花括號
{}包圍,包含零個或多個鍵值對,鍵是字符串,值可以是任何有效的 JSON 數據類型。 - 數組 (Array): 用方括號
[]包圍,包含零個或多個值,值之間用逗號分隔。 - 字符串 (String): 用雙引號
""包圍的字符序列。 - 數字 (Number): 整數或浮點數。
- 布爾值 (Boolean):
true或false - 空值 (Null):
null
例如:
people.json文件:
[
{
"name": "張三",
"gender": "男",
"age": 25
},
{
"name": "李四",
"gender": "女",
"age": 23
}
]
二、python中JSON模塊
Python 的 JSON模塊是處理 JSON 數據的標準工具。它提供了四個核心函數用於在 JSON 字符串/文件和 Python 對象之間進行轉換:
2.1 json.load()
從 JSON文件對象讀取並解析為Python 對象。
json.load(fp, *, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
- 參數:
fp: 一個支持.read()方法的文本文件對象,數據從這個文件對象中讀取。clsobject_hookparse_float(可選): 一個函數,用於將 JSON 中的浮點數字符串轉換為 Python 對象。默認是float。parse_intparse_constant(可選): 一個函數,用於處理 JSON 常量 ('-Infinity','Infinity','NaN')。object_pairs_hook(可選): 一個函數,接收一個由(key, value)對組成的列表,並返回一個對象。object_pairs_hook優先於object_hook。**kw
- 返回值: 一個 Python 對象(通常是
dict或list)。
2.2 json.loads()
從JSON 字符串(str)讀取並解析為 Python 對象。
json.loads(s, *, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
參數同
json.dump。
2.3 json.load()
將 Python 對象 編碼為 JSON格式寫入文件。
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)
- 參數:
obj: 一個必需的參數。要序列化的 Python 對象。它必須是dict,list,tuple,str,int,float,bool,None,或者是一個實現了__json__()方法的對象。fp: 一個必需的參數。一個支持.write()方法的文本文件對象(通常由open()函數返回,模式為'w'或'a')。JSON 數據將寫入這個文件對象。skipkeys(可選): 如果為True,當字典的鍵不是基本類型(str,int,float,bool,None)時,會自動跳過該鍵值對,而不是引發TypeError。ensure_ascii(可選): 如果為True,輸出將確保所有非 ASCII 字符都被轉義。如果為False,則允許直接輸出這些字符(通常用於生成人類可讀的文件)。check_circular(可選): 如果為True,會檢查容器類型的循環引用(如列表包含自身),如果發現則引發ValueError。如果為False,則不檢查,但遇到循環引用時行為未定義。allow_nan(可選): 如果為True,允許float類型的NaN,Infinity,-Infinity。如果為False,則在序列化這些值時會引發ValueError。cls(可選): 用於自定義 JSON 編碼器的類。indent(可選): 用於美化輸出。如果是一個非負整數或字符串(如'\t'),則 JSON 數組元素和對象成員將被換行並使用該值進行縮進,使其更易讀。None(默認)表示單行輸出。separators(可選): 一個(item_separator, key_separator)元組。默認是(', ', ': ')。可以設置為(',', ':')以減少輸出大小(去除空格)。default(可選): 一個函數,用於處理json模塊無法序列化的對象。該函數應返回一個可序列化的對象,或者引發TypeError。sort_keys(可選): 如果為True,則字典的輸出將按鍵的字符串表示進行排序。**kw(可選): 其他關鍵字參數。
- 返回值: 無 (
None)。
2.4 json.dumps()
將 Python 對象 編碼為 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)
參數同
json.dump。
三、數據格式轉換規則
Python 對象與 JSON 值之間的轉換規則是數據處理的關鍵。
Python-JSON 數據類型映射表
|
JSON
|
Python
|
|
object |
dict |
|
array |
list |
|
string |
str |
|
number (int) |
int |
|
number (real) |
float |
|
true |
True |
|
false |
False |
|
null |
None |
注意:
- JSON 的
null對應 Python 的None。 - JSON 的
true/false對應 Python 的True/False。
四、異常處理
JSONDecodeError 是 ValueError 的一個子類,提供了更豐富的錯誤信息,當解析 JSON 文檔時發生錯誤(即 JSON 格式不正確)時會引發此異常,這對於調試 JSON 格式問題非常有幫助。
(該異常在 Python 3.5 版本中添加)
exception json.JSONDecodeError(msg, doc, pos)
額外的屬性:
msg: 未格式化的錯誤消息(即描述錯誤原因的文本)。doc: 正在被解析的原始 JSON 文檔(字符串)。pos: 在doc字符串中,解析失敗開始的索引位置(從 0 開始的字符位置)。lineno: 與pos位置對應的行號(從 1 開始計數)。colno: 與pos位置對應的列號(從 1 開始計數)。
示例:
新建一個bad.json文件:
{
"name": "Alice",
"age": 30, // 這裏多了一個逗號
}
嘗試解析它:
import json
try:
with open('bad.json', 'r') as file:
data = json.load(file)
except json.JSONDecodeError as e:
print(f"錯誤消息: {e.msg}")
print(f"錯誤位置: 第 {e.lineno} 行, 第 {e.colno} 列")
print(f"錯誤索引: {e.pos}")
# 如果需要,可以打印整個文檔或相關部分
# print(f"文檔: {e.doc}")
可能的輸出:
錯誤消息: Expecting property name enclosed in double quotes
錯誤位置: 第 3 行, 第 2 列
錯誤索引: 35
五、完整示例
解析第一章節中的people.json文件:
import json
# 1. 定義文件名
filename = 'people.json'
try:
# 2. 打開文件並讀取
with open(filename, 'r', encoding='utf-8') as file:
# 3. 使用 json.load() 解析文件內容
data = json.load(file)
# 4. 打印解析結果,驗證數據類型和內容
print("=== 解析結果 ===")
print("原始數據類型:", type(data)) # <class 'list'>
print("解析後的數據 (Python 列表):")
print(data)
print("\n")
# 5. 訪問和使用數據
print("=== 信息 ===")
for person in data:
print(f"{person['name']} - {person['gender']}, {person['age']}歲")
except FileNotFoundError:
print(f"錯誤:找不到文件 '{filename}'。")
print("請確保 'people.json' 文件存在於當前目錄,或者檢查文件名是否正確。")
except Exception as e:
print(f"發生未知錯誤: {e}")
結果:
=== 解析結果 ===
原始數據類型: <class 'list'>
解析後的數據 (Python 列表):
[{'name': '張三', 'gender': '男', 'age': 25}, {'name': '李四', 'gender': '女', 'age': 23}]
=== 信息 ===
張三 - 男, 25歲
李四 - 女, 23歲
參考
- python官方文檔