目錄
pickle:
Python 中的pickle 是一個內置模塊,用于序列化和反序列化 Python 對象結構。序列化是將對象轉換成字節流的過程,這樣對象就可以被存儲到文件中或者通過網絡傳輸。反序列化則是將這些字節流重新轉換成原始對象的過程。
json:
json模塊是 Python 中用于處理 JSON 數據格式的內置模塊。JSON(JavaScript Object Notation)是一種文本格式,用于在不同系統之間傳輸數據。它基于 JavaScript 的對象和數組表示,但已經被許多編程語言支持,包括 Python。
問題引入:
使用 pickle 模塊序列化和反序列化
使用 json 模塊序列化和反序列化
pickle用法:
語法概覽
示例
序列化(Pickle)
json的用法
語法概覽
示例
pickle:
Python 中的pickle 是一個內置模塊,用于序列化和反序列化 Python 對象結構。序列化是將對象轉換成字節流的過程,這樣對象就可以被存儲到文件中或者通過網絡傳輸。反序列化則是將這些字節流重新轉換成原始對象的過程。
json:
json模塊是 Python 中用于處理 JSON 數據格式的內置模塊。JSON(JavaScript Object Notation)是一種文本格式,用于在不同系統之間傳輸數據。它基于 JavaScript 的對象和數組表示,但已經被許多編程語言支持,包括 Python。
問題引入:
# define a dict object
obj={"name":"Bonnie","isAGirl":True,"age":22,"hobbies":["guitar","singing","traveling"]"ss":None
}
# 將obj寫入已打開的二進制文件,序列化
f =open("test.txt","w")
f.write(obj)
報錯:
Traceback (most recent call last):File "E:\桌面\計算機\全棧\django\django項目\untitled1\ll.py", line 10, in <module>f.write(obj)
TypeError: write() argument must be str, not dict
原因:
在 Python 中,不能直接使用 write 方法將字典對象寫入文件,因為 write 方法只能處理字符串或字節序列。要將字典對象序列化并寫入文件,你需要使用 pickle 模塊。以下是如何使用 pickle 模塊將字典對象序列化并寫入文件的正確方式:
python
import pickle# 定義一個字典對象
obj = {"name": "Bonnie","isAGirl": True,"age": 22,"hobbies": ["guitar", "singing", "traveling"]
}# 使用 'wb' 模式打開文件,以便寫入二進制數據
with open("test.pkl", "wb") as f:# 使用 pickle.dump 將對象序列化并寫入文件pickle.dump(obj, f)
請注意以下幾點:
- 文件模式應為 'wb',表示以二進制寫入模式打開文件。
- 使用 pickle.dump 而不是 f.write 來序列化對象并寫入文件。
- 我將文件擴展名從 .txt 改為 .pkl,以表明這是一個使用 pickle 模塊序列化的文件。
如果你想要從這個文件中讀取并反序列化對象,可以使用以下代碼:
python
# 使用 'rb' 模式打開文件,以便讀取二進制數據
with open("test.pkl", "rb") as f:# 使用 pickle.load 從文件中讀取并反序列化對象loaded_obj = pickle.load(f)
print(loaded_obj)
這將輸出原始字典對象。
那問題json處理可以嗎?
讓我們通過一個例子來比較 pickle 和 json 模塊在處理 Python 中特殊數據類型時的不同。
首先,我們定義一個包含 Python 特殊數據類型和自定義對象的復雜數據結構:
python
class Person:def __init__(self, name, age):self.name = nameself.age = age# 創建一個包含特殊數據類型和自定義對象的字典
complex_obj = {"name": "Bonnie","is_girl": True,"age": 22,"hobbies": ["guitar", "singing", "traveling"],"nothing": None,"bytes_data": b"byte data","person": Person("Bonnie", 22)
}
使用 pickle 模塊序列化和反序列化
使用 pickle 可以輕松地序列化和反序列化上述包含特殊數據類型的復雜對象:
python
import pickle# 使用 pickle 序列化對象
with open('complex_obj.pkl', 'wb') as f:pickle.dump(complex_obj, f)# 使用 pickle 反序列化對象
with open('complex_obj.pkl', 'rb') as f:loaded_obj = pickle.load(f)print(loaded_obj)
pickle 模塊能夠處理 None、bytes 類型以及自定義對象 Person,并且能夠保持對象的結構和類型。
使用 json 模塊序列化和反序列化
當我們嘗試使用 json 模塊來序列化相同的對象時,會遇到問題:
python
import json# 嘗試使用 json 序列化對象
try:json_string = json.dumps(complex_obj)
except TypeError as e:print("JSON serialization error:", e)
這段代碼會拋出一個 TypeError,因為 json.dumps() 無法處理 None 類型、bytes 類型和自定義對象 Person。為了能夠使用 json 序列化,我們需要定義一個自定義的序列化函數來處理這些特殊類型:
python
def my_encoder(obj):if isinstance(obj, bytes):return obj.decode('utf-8') # 假設 bytes 對象是 UTF-8 編碼的字符串raise TypeError(f"Object of type '{obj.__class__.__name__}' is not JSON serializable")# 使用自定義的序列化函數
json_string = json.dumps(complex_obj, default=my_encoder)# 將 JSON 字符串寫入文件
with open('complex_obj.json', 'w') as f:f.write(json_string)# 反序列化時,我們失去了類型信息,只能得到一個普通的字典
loaded_obj_json = json.loads(json_string)
print(loaded_obj_json)
在這個例子中,我們定義了一個 my_encoder 函數來處理 bytes 類型,將其解碼為字符串。但是,對于 None 類型和自定義對象 Person,我們仍然無法直接序列化。即使對于 bytes,我們也失去了原始的二進制數據,因為它被解碼為了字符串。
通過這個例子,你可以看到 pickle 和 json 在處理特殊數據類型時的不同。pickle 更加靈活,能夠處理幾乎所有的 Python 對象,而 json 則更加通用和安全,但需要處理一些數據類型的兼容性問題。
pickle用法:
語法概覽
Pickle 提供了幾個函數來處理序列化和反序列化:
- pickle.dump(obj, file, protocol=None, *, fix_imports=True): 將對象 obj 序列化并寫入到文件對象 file 中。
- pickle.dumps(obj, protocol=None, *, fix_imports=True): 將對象 obj 序列化并返回一個字節串。
- pickle.load(file, *, fix_imports=True, encoding="ASCII", errors="strict"): 從文件對象 file 中讀取字節流并反序列化成 Python 對象。
- pickle.loads(bytes_object, *, fix_imports=True): 從字節串 bytes_object 中讀取字節流并反序列化成 Python 對象。
其中,protocol 參數決定了使用的序列化協議版本,可以是以下之一:
- pickle.HIGHEST_PROTOCOL: 使用最高的協議版本。
- pickle.DEFAULT_PROTOCOL: 使用默認的協議版本。
- 0: 表示原始協議。
- 1: 表示文本模式。
- 2: 表示二進制模式,更高效。
示例
序列化(Pickle)
import pickledata = {'name': 'Alice', 'age': 30, 'city': 'New York'}# 使用pickle.dumps將字典對象序列化為字節流
serialized_data = pickle.dumps(data)# 使用pickle.loads將字節流反序列化為原始對象
deserialized_data = pickle.loads(serialized_data)print(deserialized_data)
# 輸出: {'name': 'Alice', 'age': 30, 'city': 'New York'}# 使用pickle.dump將字典對象序列化并寫入文件
with open('data.pickle', 'wb') as file:pickle.dump(data, file)# 使用pickle.load從文件中讀取字節流并反序列化為原始對象
with open('data.pickle', 'rb') as file:loaded_data = pickle.load(file)print(loaded_data)
# 輸出: {'name': 'Alice', 'age': 30, 'city': 'New York'}
json的用法
語法概覽
json模塊中的主要函數和方法如下:
- `json.dumps(obj, indent=None)`
將Python對象`obj`編碼為JSON格式的字符串,并返回結果。如果指定了`indent`參數,它將定義縮進的級別,使得生成的JSON字符串具有更好的可讀性。
- `json.loads(json_str)`
將JSON格式的字符串`json_str`解碼為Python對象,并返回結果。
- `json.dump(obj, file, indent=None)`
將Python對象`obj`編碼為JSON格式的字符串,并將結果寫入文件對象`file`中。如果指定了`indent`參數,它將定義縮進的級別。
- `json.load(file)`
從文件對象`file`中讀取JSON格式的字符串,并將其解碼為Python對象。
示例
下面是一個簡單的示例,演示如何使用json模塊進行編碼和解碼:
import jsondata = {'name': 'Alice', 'age': 30, 'city': 'New York'}# 將Python對象編碼為JSON字符串
json_str = json.dumps(data)
print(json_str)
# 輸出: {"name": "Alice", "age": 30, "city": "New York"}# 將JSON字符串解碼為Python對象
decoded_data = json.loads(json_str)
print(decoded_data)
# 輸出: {'name': 'Alice', 'age': 30, 'city': 'New York'}# 將Python對象編碼為JSON字符串,并寫入文件
with open('data.json', 'w') as file:json.dump(data, file)# 從文件中讀取JSON字符串,并解碼為Python對象
with open('data.json', 'r') as file:loaded_data = json.load(file)print(loaded_data)
# 輸出: {'name': 'Alice', 'age': 30, 'city': 'New York'}
需要注意的是,JSON只支持一些基本數據類型,如字符串、數字、布爾值、列表、字典和None。Python對象中的其他類型,如函數、類實例和特殊對象,可能無法直接轉換為JSON字符串。可以使用`json.dump()`和`json.load()`函數配合自定義的編碼和解碼函數來處理這些特殊類型的對象。此外,json模塊還提供了格式化輸出、排序鍵、編碼和解碼的擴展選項,可以根據具體需求進行配置。