三十、深入Python中的Pickle和Json模組
@Author: Runsen
聽過Python序列化pickle和Json標準庫嗎?
pickle
pickle模組是以二進位的形式序列化後保存到文件中(保存文件的後綴為”.pkl
“),不能直接打開進行預覽。而python的另一個序列化標準模組 json
,可以直接打開查看(例如在notepad++
中查看)。
pickle
模組實現了基本的數據序列化和反序列化。
所謂的序列化 (Serialization)
是將對象的狀態資訊轉換為可以存儲或傳輸的形式的過程,比如數據轉成文本。
就是將數據結構轉化成你看不懂的東西。相反的,從序列化的格式中解析對象狀態的過程被稱為「反序列化」。
pickle提供四個功能:dumps
,dump
,loads
,load
, 和json
差不多。
dump和dumps
序列化的方法為 pickle.dump()和pickle.dumps()。
dump該方法的相關參數如下:
pickle.dump(obj, file, protocol=None,*,fix_imports=True)
該方法實現的是將序列化後的對象obj以二進位形式寫入文件file中,進行保存。
pickle.dumps()方法的參數如下:
pickle.dumps(obj, protocol=None,*,fix_imports=True)
pickle.dumps()方法跟 pickle.dump()方法的區別在於,pickle.dumps()
方法不需要寫入文件中,它是直接返回一個序列化的bytes對象。
下面具體一個具體示例。
>>> import pickle
>>> data = [{'a': 'A', 'b': 2, 'c': 2.22}]
>>> # 使用 pickle.dumps() 可以將一個對象轉換為二進位字元串(dump string):
>>> data_string = pickle.dumps(data)
>>> data
[{'a': 'A', 'b': 2, 'c': 2.22}]
>>>< data_string
b'\x80\x03]q\x00}q\x01(X\x01\x00\x00\x00aq\x02X\x01\x00\x00\x00Aq\x03X\x01\x00\x00\x00bq\x04K\x02X\x01\x00\x00\x00cq\x05G@\x01\xc2\x8f\\(\xf5\xc3ua.'
dumps 可以接受一個可省略的 protocol 參數(默認為 0),protocol參數不同,表示進行的編碼協議不同,得到的data_string
也不同。
如果 protocol 參數指定為負數,那麼將調用當前的最高級的編碼協議進行編碼
>>> data_string_1 = pickle.dumps(data, 1)
>>> data_string_1
b']q\x00}q\x01(X\x01\x00\x00\x00aq\x02X\x01\x00\x00\x00Aq\x03X\x01\x00\x00\x00bq\x04K\x02X\x01\x00\x00\x00cq\x05G@\x01\xc2\x8f\\(\xf5\xc3ua.'
>>> data_string__1 = pickle.dumps(data, -1)
>>> data_string__1
b'\x80\x04\x95#\x00\x00\x00\x00\x00\x00\x00]\x94}\x94(\x8c\x01a\x94\x8c\x01A\x94\x8c\x01b\x94K\x02\x8c\x01c\x94G@\x01\xc2\x8f\\(\xf5\xc3ua.'
如果需要保存為data.pkl,可以使用dump方法,具體程式碼如下。
import pickle
with open('data.pkl', 'wb') as f:
pickle.dump(data, f)
load和loads
現在給你這個data_string
你能知道這是啥嗎?
雖然 pickle 編碼的字元串並不一定可讀,但是我們可以用 pickle.loads()
來從這個字元串中恢復原對象中的內容(load string)。也就是dumps
和loads
有相反的作用。
pickle.loads()方法的參數如下:
pickle.loads(bytesobject, *,fiximports=True, encoding="ASCII". errors="strict")
>>> # pickle.loads() 來從這個字元串中恢復原對象中的內容(load string):
>>> pickle.loads(data_string)
[{'a': 'A', 'b': 2, 'c': 2.22}]
如果指定了protocol參數,需要這些格式中恢復對象時,不需要指定所用的協議,pickle.load() 會自動識別:
>>> pickle.loads(data_string_1)
[{'a': 'A', 'b': 2, 'c': 2.22}]
>>> pickle.loads(data_string__1)
[{'a': 'A', 'b': 2, 'c': 2.22}]
反序列化的方法還有 pickle.load()
,該方法的相關參數如下:
pickle.load(file, *,fix_imports=True, encoding="ASCII". errors="strict")
如果使用load,需要讀取data.pkl文件。
pkl_file = open('data.pkl', 'rb')
print(pickle.load(pkl_file))
pickle.loads()方法跟 pickle.load()方法的區別在於, pickle.loads()方法是直接從bytes對象中讀取序列化的資訊,而非從文件中讀取。
Json
JSON(JavaScript Object Notation, JS 對象簡譜) 是一種輕量級的數據交換格式。
它基於 ECMAScript (歐洲電腦協會制定的js規範)的一個子集,採用完全獨立於程式語言的文本格式來存儲和表示數據。簡潔和清晰的層次結構使得 JSON 成為理想的數據交換語言。易於人閱讀和編寫,同時也易於機器解析和生成,並有效地提升網路傳輸效率。
JS對象
var student = {
name: 『Runsen』,
age: 18,
feature : [『高』, 『富』, 『帥』]
}
JSON字元串
{
「name」: 「Runsen」,
「age」: 18,
「 feature 「 : [『高』, 『富』, 『帥』]
}
Python字典
{
『name』: 『Runsen』,
『age』: 18
『feature』 : [『高』, 『富』, 『帥』]
}
注意點:Json字元串
必須用雙引號(即:」」)
來包括, 值可以是字元串、數字、true、false、null、列表,或字典。
Python字典可以用單引號,也可以用雙引號。
常用json就知道,json和pickle完全一樣,json模組也提供了四個常用的方法:dumps、dump、loads、load,用於字元串 和 python數據類型間進行轉換。
APi | 描述 |
---|---|
json.dumps(obj) | 將python數據轉化為json |
json.loads(s) | 將json數據轉換為python的數據 |
json.dump(obj, fp) | 轉換為json並保存到文件中 |
json.load(fp) | 從文件中讀取json,並轉化為python數據 |
API的使用
import json
my_dict = {'a':'1','b':'2','c':'3','d':'4'}
print(type(my_dict))
a = json.dumps(my_dict)
print(a)
print(type(a))
b=json.loads(a)
print(b)
print(type(b))
# 輸出如下
<class 'dict'>
{"a": "1", "b": "2", "c": "3", "d": "4"}
<class 'str'> #json的字元串
{'a': '1', 'b': '2', 'c': '3', 'd': '4'}
<class 'dict'>
——————————
>>> import json
>>> print (json.dumps('中國'))
"\u4e2d\u56fd"
>>> # 這裡有一個ensure_ascii參數,表示是否用ascii解析
>>> print(json.dumps('中國', ensure_ascii=False))
"中國"
——————————
#json.dump() 和 json.load() 來編碼和解碼JSON數據,用於處理文件。
import json
my_dict = {'a':'1','b':'2','c':'3','d':'4'}
json.dump(my_dict,open('a.txt','w'))
print(json.load(open('a.txt','r')))
# 輸出如下
會生成一個「a.txt"文件
{'a': '1', 'b': '2', 'c': '3', 'd': '4'}
本文已收錄 GitHub,傳送門~ ,裡面更有大廠面試完整考點,歡迎 Star。