首頁 > 軟體

用來將物件持久化的python pickle模組

2022-05-26 14:02:07

前言

pickle 模組可以對一個 Python 物件的二進位制進行序列化和反序列化。說白了,就是它能夠實現任意物件與二進位制直接的相互轉化,也可以實現物件與文字之間的相互轉化。

比如,我程式裡有一個 python 物件,我想把它存到磁碟裡,於是我用 pickle 把他轉到一個文字裡。當後面我想使用的時候,讀取出來時候依然是一個 python 物件。

一、pickle 模組下的方法

pickle 模組提供了以下 4 種方法:

  • dump():將 Python 中的物件序列化成二進位制物件,並寫入檔案
  • load():讀取指定的序列化資料檔案,並返回物件
  • dumps():將 Python 中的物件序列化成二進位制物件,並直接返回,而不是將其寫入到檔案
  • loads():讀取給定的二進位制物件資料,並將其轉換為 Python 物件

1. dumps()

將 Python 中的物件序列化成二進位制物件,並直接返回。

範例

import pickle
test_list = ["pingguo", {1, 2, 3}, None]
# 使用 dumps() 函數將 test_list 轉成 p1
p1 = pickle.dumps(test_list)
print(p1)
print("返回型別:", type(p1))

輸出結果:

b'x80x03]qx00(Xx07x00x00x00pingguoqx01cbuiltinsnsetnqx02]qx03(Kx01Kx02Kx03ex85qx04Rqx05Ne.'
返回型別: <class 'bytes'>

2. loads()

讀取給定的二進位制物件資料,並將其轉換為 Python 物件。

範例在上面的基礎上繼續:

import pickle
test_list = ["pingguo", {1, 2, 3}, None]
# 使用 dumps() 函數將 test_list 轉成 p1
p1 = pickle.dumps(test_list)
print(p1)
print("返回型別:", type(p1))
# 使用 loads() 函數將 p1 轉成 Python 物件 p2
p2 = pickle.loads(p1)
print(p2)
print("返回型別:", type(p2))

輸出結果:

b'x80x03]qx00(Xx07x00x00x00pingguoqx01cbuiltinsnsetnqx02]qx03(Kx01Kx02Kx03ex85qx04Rqx05Ne.'
返回型別: <class 'bytes'>
['pingguo', {1, 2, 3}, None]
返回型別: <class 'list'>

pickle 反序列化後的物件與原物件是等值的副本物件,類似deepcopy。

3. dump()

將 Python 中的物件序列化成二進位制物件,並寫入檔案。

範例

import pickle
test_list = ["pingguo", {1, 2, 3}, None]
with open("test_pickle.txt", "wb") as f:
    # 使用 dump() 函數將 test_list 轉成 p1,寫到txt文字裡
    pickle.dump(test_list, f)

注意這裡的寫檔案是 "wb",以二進位制格式開啟一個檔案只用於寫入,否則會報錯。

執行成功後,同級目錄下生成一個test_pickle.txt檔案,因為是二進位制內容,直接開啟看到的是亂碼。

4. load()

讀取指定的序列化資料檔案,並返回物件。

範例

import pickle
test_list = ["pingguo", {1, 2, 3}, None]
with open("test_pickle.txt", "wb") as f:
    # 使用 dump() 函數將 test_list 轉成 p1,寫到txt文字裡
    pickle.dump(test_list, f)
with open("test_pickle.txt", "rb") as f:
    # 將二進位制檔案物件轉換成 Python 物件 p3
    p3 = pickle.load(f)
    print(p3)
    print("型別:", type(p3))

注意,這裡讀取檔案用rb,也就是以二進位制格式開啟一個檔案用於唯讀。

執行成功。

['pingguo', {1, 2, 3}, None]
型別: <class 'list'>

二、可以被 pickle 封存/解封的物件

下列型別可以被封存:

  • None、True 和 False
  • 整數、浮點數、複數
  • str、byte、bytearray
  • 只包含可封存物件的集合,包括 tuple、list、set 和 dict
  • 定義在模組最外層的函數(使用 def 定義,lambda 函數則不可以)
  • 定義在模組最外層的內建函數
  • 定義在模組最外層的類
  • 某些類範例,這些類的 dict 屬性值或 getstate() 函數的返回值可以被封存。

三、pickle 與 json 的區別

python 提供的 json 標準庫相信大家都熟悉,提供的方法也與 pickle 相似,那麼兩者有什麼區別呢?

  • JSON 是一個文字序列化格式,pickle 是一個二進位制序列化格式。
  • JSON 是我們可以直觀閱讀的,而 pickle 不行。
  • JSON是可互操作的,在Python之外也可以使用,而pickle則是Python專用的。
  • 預設情況下,JSON 只能表示 Python 內建型別的子集,不能表示自定義的類;但 pickle 可以表示大量的 Python 資料型別。
  • JSON不像 pickle,對一個不信任的JSON進行反序列化的操作本身不會造成任意程式碼執行漏洞。

關於最後一點,說的是 pickle 模組並不安全。很有可能你去解封的是惡意構建的 pickle 資料,造成解封時執行了惡意程式碼,所以要慎用。

以上就是用來將物件持久化的python pickle模組的詳細內容,更多關於python物件持久化pickle模組的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com