pickle 在python 2和python 3中相容性問題

Inside_Zhang發表於2015-11-25

以下的演示均在python 3環境下進行。

我們以一個簡單的檔案開啟和檔案讀為例說明,pickle讀檔案時可能存在的編碼問題:

import gzip
import pickle

# 使用with結構避免手動的檔案關閉操作
with gzip.open('./mnist.pkl.gz', 'rb') as f:
    training_data, validation_data, test_data = pickle.load(f)

如果沿用python 2.x的做法,如上所示,而不做任何編碼格式上的設定,直接執行,編譯器會提示如下錯誤:

UnicodeDecodeError: 'ascii' codec can't decode byte 0x90 in position 614: ordinal not in range(128)

0. 一種 import 的相容性解決思路

try:
    import cPickle as pickle
except ImportError:
    import pickle

1. 解決方案

一種可行的解決方案是:

with gzip.open('./mnist.pkl.gz', 'rb') as f:
    u = pickle._Unpickler(f)
    u.encoding = 'latin1'
    training_data, validation_data, test_data = u.load()

或者更為精煉地:

with gzip.open('./mnist.pkl.gz', 'rb') as f:
    training_data, validation_data, test_data = pickle.load(f, encoding='latin1')

references

[1] <Pickle incompatability of numpy arrays between Python 2 and 3>

相關文章