Linux程式設計之序列化儲存Python物件(下)(轉)
Linux程式設計之序列化儲存Python物件(下)(轉)[@more@] 相等,但並不總是相同
正如在上一個示例所暗示的,只有在這些物件引用記憶體中同一個物件時,它們才是相同的。在 pickle 情形中,每個物件被恢復到一個與原來物件相等的物件,但不是同一個物件。換句話說,每個 pickle 都是原來物件的一個副本:
>>> j = [1, 2, 3]
>>> k = j
>>> k is j
1
>>> x = pickle.dumps(k)
>>> y = pickle.loads(x)
>>> y
[1, 2, 3]
>>> y == k
1
>>> y is k
0
>>> y is j
0
>>> k is j
1
清單 8. 作為原來物件副本的被恢復的物件
同時,我們看到 Python 能夠維護物件之間的引用,這些物件是作為一個單元進行 pickle 的。然而,我們還看到分別呼叫 dump() 會使 Python 無法維護對在該單元外部進行 pickle 的物件的引用。相反,Python 複製了被引用物件,並將副本和被 pickle 的物件儲存在一起。對於 pickle 和恢復單個物件層次結構的應用程式,這是沒有問題的。但要意識到還有其它情形。
值得指出的是,有一個選項確實允許分別 pickle 物件,並維護相互之間的引用,只要這些物件都是 pickle 到同一檔案即可。pickle 和 cPickle 模組提供了一個 Pickler(與此相對應是 Unpickler),它能夠跟蹤已經被 pickle 的物件。透過使用這個 Pickler,將會透過引用而不是透過值來 pickle 共享和迴圈引用:
>>> f = file('temp.pkl', 'w')
>>> pickler = pickle.Pickler(f)
>>> pickler.dump(a)
>>> pickler.dump(b)
>>> f.close()
>>> f = file('temp.pkl', 'r')
>>> unpickler = pickle.Unpickler(f)
>>> c = unpickler.load()
>>> d = unpickler.load()
>>> c[2]
[3, 4, [1, 2, [...]]]
>>> d[2]
[1, 2, [3, 4, [...]]]
>>> c[2] is d
1
>>> d[2] is c
1
清單 9. 維護分別 pickle 的物件間的引用
不可 pickle 的物件
一些物件型別是不可 pickle 的。例如,Python 不能 pickle 檔案物件(或者任何帶有對檔案物件引用的物件),因為 Python 在 unpickle 時不能保證它可以重建該檔案的狀態(另一個示例比較難懂,在這類文章中不值得提出來)。試圖 pickle 檔案物件會導致以下錯誤:
>>> f = file('temp.pkl', 'w')
>>> p = pickle.dumps(f)
Traceback (most recent call last):
File "", line 1, in ?
File "/usr/lib/python2.2/copy_reg.py", line 57, in _reduce
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle file objects
清單 10. 試圖 pickle 檔案物件的結果
正如在上一個示例所暗示的,只有在這些物件引用記憶體中同一個物件時,它們才是相同的。在 pickle 情形中,每個物件被恢復到一個與原來物件相等的物件,但不是同一個物件。換句話說,每個 pickle 都是原來物件的一個副本:
>>> j = [1, 2, 3]
>>> k = j
>>> k is j
1
>>> x = pickle.dumps(k)
>>> y = pickle.loads(x)
>>> y
[1, 2, 3]
>>> y == k
1
>>> y is k
0
>>> y is j
0
>>> k is j
1
清單 8. 作為原來物件副本的被恢復的物件
同時,我們看到 Python 能夠維護物件之間的引用,這些物件是作為一個單元進行 pickle 的。然而,我們還看到分別呼叫 dump() 會使 Python 無法維護對在該單元外部進行 pickle 的物件的引用。相反,Python 複製了被引用物件,並將副本和被 pickle 的物件儲存在一起。對於 pickle 和恢復單個物件層次結構的應用程式,這是沒有問題的。但要意識到還有其它情形。
值得指出的是,有一個選項確實允許分別 pickle 物件,並維護相互之間的引用,只要這些物件都是 pickle 到同一檔案即可。pickle 和 cPickle 模組提供了一個 Pickler(與此相對應是 Unpickler),它能夠跟蹤已經被 pickle 的物件。透過使用這個 Pickler,將會透過引用而不是透過值來 pickle 共享和迴圈引用:
>>> f = file('temp.pkl', 'w')
>>> pickler = pickle.Pickler(f)
>>> pickler.dump(a)
>>> pickler.dump(b)
>>> f.close()
>>> f = file('temp.pkl', 'r')
>>> unpickler = pickle.Unpickler(f)
>>> c = unpickler.load()
>>> d = unpickler.load()
>>> c[2]
[3, 4, [1, 2, [...]]]
>>> d[2]
[1, 2, [3, 4, [...]]]
>>> c[2] is d
1
>>> d[2] is c
1
清單 9. 維護分別 pickle 的物件間的引用
不可 pickle 的物件
一些物件型別是不可 pickle 的。例如,Python 不能 pickle 檔案物件(或者任何帶有對檔案物件引用的物件),因為 Python 在 unpickle 時不能保證它可以重建該檔案的狀態(另一個示例比較難懂,在這類文章中不值得提出來)。試圖 pickle 檔案物件會導致以下錯誤:
>>> f = file('temp.pkl', 'w')
>>> p = pickle.dumps(f)
Traceback (most recent call last):
File "", line 1, in ?
File "/usr/lib/python2.2/copy_reg.py", line 57, in _reduce
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle file objects
清單 10. 試圖 pickle 檔案物件的結果
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617542/viewspace-963071/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- python之物件導向程式設計(一)Python物件程式設計
- Python學習之物件導向程式設計Python物件程式設計
- 小程式 LRU 儲存設計
- Python 黑帽程式設計 4.2 Sniffer 之資料本地儲存和載入Python程式設計
- Linux 下的程式間通訊:共享儲存Linux
- 儲存—物件儲存_Minio物件
- Python標準庫分享之儲存物件 (pickle包,cPickle包)Python物件
- Python學習之物件導向高階程式設計Python物件程式設計
- Python物件導向程式設計Python物件程式設計
- Python 物件導向程式設計Python物件程式設計
- 塊儲存 檔案儲存 物件儲存物件
- DAOS 分散式非同步物件儲存|架構設計分散式非同步物件架構
- 物件儲存物件
- 我們NetCore下日誌儲存設計NetCore
- Python 物件導向程式設計之封裝的藝術Python物件程式設計封裝
- Python - 物件導向程式設計 - 三大特性之繼承Python物件程式設計繼承
- 資料庫表設計之儲存引擎資料庫儲存引擎
- Python OOP 物件導向程式設計PythonOOP物件程式設計
- python技能--物件導向程式設計Python物件程式設計
- Python物件導向程式設計(1)Python物件程式設計
- Python - 物件導向程式設計 - super()Python物件程式設計
- Python - 物件導向程式設計 - @propertyPython物件程式設計
- Linux之shell程式設計Linux程式設計
- JavaScript設計模式之物件導向程式設計JavaScript設計模式物件程式設計
- Ceph Reef(18.2.X)之python操作物件儲存閘道器Python物件
- 詳解Python物件導向程式設計之類、例項、方法Python物件程式設計
- RocketMQ高效能之底層儲存設計MQ
- 物件儲存、檔案儲存、塊儲存這三者之間有什麼區別?物件
- 好程式設計師Java實用教程系列之物件的轉型程式設計師Java物件
- python之超程式設計Python程式設計
- 好程式設計師Java學習路線之Java中的物件流和序列化程式設計師Java物件
- 全網最適合入門的物件導向程式設計教程:57 Python字串與序列化-序列化與反序列化物件程式設計Python字串
- 史上最全 Python 物件導向程式設計Python物件程式設計
- python基礎(物件導向程式設計)Python物件程式設計
- python物件導向程式設計基礎Python物件程式設計
- 關於Python的面相物件程式設計Python物件程式設計
- 14 Python物件導向程式設計:反射Python物件程式設計反射
- 圖解python | 物件導向程式設計圖解Python物件程式設計
- Linux程式設計之gdb(二)Linux程式設計