2.1 模組 json
JSON (JavaScript Object Notation) 是一種輕量的資料交換格式,易於人類閱讀和撰寫,同時也易於電腦解析和生成。JSON 常用於在伺服器和 web 應用程式之間傳遞數據,以及用於儲存配置和設置。
模組 json
在 Python 中提供了序列化(將 Python 物件轉換為 JSON 字串)和反序列化(將 JSON 字串轉換為 Python 物件)的功能。這個模組是 Python 的標準函式庫的一部分並被廣泛用於處理 JSON 數據。
模組 json
的主要功能非常類似於 pickle
,並且以相似的方式運作。標準就是這樣嘛!
-
字串處理:
-
json.dumps(obj)
— 將 Python 物件轉換為 JSON 字串。 -
json.loads(s)
— 將 JSON 字串轉換為 Python 物件。
-
-
文件處理:
-
json.dump(obj, file)
— 序列化 Python 物件並寫入文字文件。 -
json.load(file)
— 從包含 JSON 格式數據的文字文件中反序列化 Python 物件。
-
讓我們看看幾個例子來更好地記住這些功能的工作原理。
2.2 序列化為字串
將 Python 物件序列化為 JSON 字串
要將物件序列化為字串,只需將其傳遞給 json.dumps()
函數。
import json
# 用於序列化的物件範例
data = {
"name": "Alice",
"age": 30,
"is_student": False,
"courses": ["Math", "Science"],
"address": {
"city": "New York",
"zip_code": "10001"
}
}
# 將 Python 物件轉換為 JSON 字串
json_string = json.dumps(data, indent=4)
print("序列化數據 (JSON):", json_string)
反序列化 JSON 字串為 Python 物件
要從字串獲得物件,只需將描述物件的 JSON 字串傳遞給 json.loads()
方法。
import json
# 用於反序列化的 JSON 字串範例
json_string = '''
{
"name": "Alice",
"age": 30,
"is_student": false,
"courses": ["Math", "Science"],
"address": {
"city": "New York",
"zip_code": "10001"
}
}
'''
# 將 JSON 字串轉換為 Python 物件
data = json.loads(json_string)
print("反序列化數據 (Python):", data)
2.3 序列化為文件
將 Python 物件寫入 JSON 格式的文件
要將物件寫入文件中,可以調用 json.dump()
方法。處理文件時,使用異常處理來正確處理可能的錯誤是很重要的。以下是一個例子:
import json
# 用於序列化的物件範例
data = {
"name": "Bob",
"age": 25,
"is_student": True,
"courses": ["History", "Literature"],
"address": {
"city": "Los Angeles",
"zip_code": "90001"
}
}
# 使用異常處理將 Python 物件寫入 JSON 文件
try:
with open('data.json', 'w') as file:
json.dump(data, file, indent=4)
print("數據已成功寫入文件。")
except IOError:
print("寫入文件時出錯。")
except json.JSONEncodeError:
print("編碼 JSON 時出錯。")
從 JSON 格式的文件中讀取 Python 物件
讀取文件也很簡單——只需將文件傳遞給 json.load()
方法。同樣,這裡重要的是使用異常處理:
import json
# 使用異常處理從 JSON 文件中讀取 Python 物件
try:
with open('data.json', 'r') as file:
data = json.load(file)
print("從文件中反序列化數據 (Python):", data)
except IOError:
print("讀取文件時出錯。")
except json.JSONDecodeError:
print("解碼 JSON 時出錯。")
2.4 函數的附加參數
在處理序列化的函數中,可以傳遞其它參數來使您的 JSON 更漂亮:
-
skipkeys
: 若為True
,則跳過不為字串、數字或None
的鍵。 -
ensure_ascii
: 若為True
,所有非 ASCII 字元將使用 Unicode escape 序列。 -
indent
: 若指定數字,將添加縮排以提高可讀性。 -
sort_keys
: 若為True
,則 JSON 鍵將按字母順序排序。
使用 json.dumps()
參數的範例:
import json
data = {"c": 3, "b": 2, "a": 1}
# 帶鍵排序和縮排的序列化
json_string = json.dumps(data, indent=4, sort_keys=True)
print(json_string)
2.5 自定解碼器和編碼器
模組 json
允許使用自定義函數來序列化和反序列化物件。
自定義編碼器範例
首先,我們創建一個特殊的編碼器類別,該類別內部檢查
如果物件類型 == datetime,則返回物件作為 ISO 格式字串
。
import json
from datetime import datetime
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
data = {
"name": "Alice",
"timestamp": datetime.now()
}
# 使用自定義編碼器進行序列化
json_string = json.dumps(data, cls=CustomEncoder, indent=4)
print(json_string)
自定義解碼器範例
對於反向操作,我們也需要一個將字串轉換為日期的函數。例如,只需
檢查欄位名稱,如果是 timestamp,則將字串轉換為 datetime 物件
:
import json
from datetime import datetime
def custom_decoder(dct):
if 'timestamp' in dct:
dct['timestamp'] = datetime.fromisoformat(dct['timestamp'])
return dct
json_string = '''
{
"name": "Alice",
"timestamp": "2023-05-15T14:30:00"
}
'''
# 使用自定義解碼器進行反序列化
data = json.loads(json_string, object_hook=custom_decoder)
print(data)
GO TO FULL VERSION