我試圖unpickle在python3醃製的對象。這適用於python3,但不適用於python2。這個問題可以被再現至pickle協議0實施例的代碼:unpickle從python3 python2 OrderedDict
import pickle
import collections
o = collections.OrderedDict([(1,1),(2,2),(3,3),(4,4)])
f = open("test.pkl", "wb")
pickle.dump(o, f, 0)
f.close()
這導致以下PKL文件:
python2:
ccollections
OrderedDict
p0
((lp1
(lp2
I1
aI1
aa(lp3
I2
aI2
aa(lp4
I3
aI3
aa(lp5
I4
aI4
aatp6
Rp7
python3:
cUserString
OrderedDict
p0
(tRp1
L1L
L1L
sL2L
L2L
sL3L
L3L
sL4L
L4L
s.
當我嘗試從python2加載在python3中創建的pickle文件時,我收到以下異常:
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> f = open("test.pkl", "rb")
>>> p = pickle.load(f)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/pickle.py", line 1378, in load
return Unpickler(file).load()
File "/usr/lib/python2.7/pickle.py", line 858, in load
dispatch[key](self)
File "/usr/lib/python2.7/pickle.py", line 1090, in load_global
klass = self.find_class(module, name)
File "/usr/lib/python2.7/pickle.py", line 1126, in find_class
klass = getattr(mod, name)
AttributeError: 'module' object has no attribute 'OrderedDict
但是,將pickle文件中的第一行從UserString更改爲集合類可以解決問題。
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> f = open("test.pkl", "rb")
>>> p = pickle.load(f)
>>> p
OrderedDict([(1L, 1L), (2L, 2L), (3L, 3L), (4L, 4L)])
這是python3中的一個bug嗎?
AFAIK,你應該只使用完全相同major.minor版本泡菜和unpickle。 Python3的數據類型在Python2中不存在。如果你需要跨越醃菜,你應該串行到通用的格式,如XML或JSON –
這可能是正確的做法。不幸的是,我沒有控制生成pickle文件的代碼。我只需要從它讀取:( –