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物件程式設計
- Linux 程式設計之Shell程式設計(轉)Linux程式設計
- 儲存系統設計指南之儲存分類
- python之物件導向程式設計(一)Python物件程式設計
- 小程式 LRU 儲存設計
- Linux程式設計之四(轉)Linux程式設計
- Android 程式設計日誌之資料儲存Android程式設計
- Python學習之物件導向程式設計Python物件程式設計
- python物件導向程式設計之組合Python物件程式設計
- Python 黑帽程式設計 4.2 Sniffer 之資料本地儲存和載入Python程式設計
- Linux下的OpenGL程式設計(轉)Linux程式設計
- 塊儲存 檔案儲存 物件儲存物件
- 轉發:Python下VTK 程式設計Python程式設計
- Linux下C語言程式設計(轉)LinuxC語言程式設計
- 物件儲存物件
- DAOS 分散式非同步物件儲存|架構設計分散式非同步物件架構
- Delphi 中物件導向程式設計之我見 (轉)物件程式設計
- Typescript玩轉設計模式 之 物件行為型模式(下)TypeScript設計模式物件
- Python標準庫分享之儲存物件 (pickle包,cPickle包)Python物件
- Linux 下的程式間通訊:共享儲存Linux
- Python 中整型物件儲存的位置Python物件
- 【爬蟲】(七)Python資料儲存之MySQL(下)爬蟲PythonMySql
- 資料庫表設計之儲存引擎資料庫儲存引擎
- Python學習之物件導向高階程式設計Python物件程式設計
- pickle和cPickle:Python物件的序列化(下)Python物件
- Python物件導向程式設計Python物件程式設計
- Python 物件導向程式設計Python物件程式設計
- Linux下的shell程式設計入門(轉)Linux程式設計
- JavaScript設計模式之物件導向程式設計JavaScript設計模式物件程式設計
- 理解Python中整型物件儲存的位置Python物件
- Python - 物件導向程式設計 - 三大特性之繼承Python物件程式設計繼承
- Python 物件導向程式設計之封裝的藝術Python物件程式設計封裝
- PERL物件程式設計基礎(轉)物件程式設計
- java物件導向程式設計(轉)Java物件程式設計
- RocketMQ高效能之底層儲存設計MQ
- 資料儲存--面向列的儲存設計
- 物件儲存、檔案儲存、塊儲存這三者之間有什麼區別?物件
- 好程式設計師Java學習路線之Java中的物件流和序列化程式設計師Java物件