碼迷,mamicode.com
首頁 > 編程語言 > 詳細

【python】 用來將對象持久化的 pickle 模塊

時間:2021-07-28 21:34:14      閱讀:0      評論:0      收藏:0      [點我收藏+]

標簽:程序   寫入文件   漏洞   代碼執行   內置函數   對象   gets   取出   情況   

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‘\x80\x03]q\x00(X\x07\x00\x00\x00pingguoq\x01cbuiltins\nset\nq\x02]q\x03(K\x01K\x02K\x03e\x85q\x04Rq\x05Ne.‘
返回類型: <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‘\x80\x03]q\x00(X\x07\x00\x00\x00pingguoq\x01cbuiltins\nset\nq\x02]q\x03(K\x01K\x02K\x03e\x85q\x04Rq\x05Ne.‘
返回類型: <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 模塊

標簽:程序   寫入文件   漏洞   代碼執行   內置函數   對象   gets   取出   情況   

原文地址:https://www.cnblogs.com/pingguo-softwaretesting/p/15063288.html

(0)
(0)
   
舉報
評論 一句話評論(0
登錄后才能評論!
? 2014 mamicode.com 版權所有  聯系我們:gaon5@hotmail.com
迷上了代碼!
4399在线看MV_久久99精品久久久久久久久久_成人又黄又爽又刺激视频_能收黄台的app不收费