2015-11-06 65 views
2

我试图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吗?

+0

AFAIK,你应该只使用完全相同major.minor版本泡菜和unpickle。 Python3的数据类型在Python2中不存在。如果你需要跨越腌菜,你应该串行到通用的格式,如XML或JSON –

+0

这可能是正确的做法。不幸的是,我没有控制生成pickle文件的代码。我只需要从它读取:( –

回答

1

确保你在Python 2这段代码导入collections工作对我来说:

的Python 3 - 做酸洗:

import pickle 
import collections 

o = collections.OrderedDict([(1,1),(2,2),(3,3),(4,4)]) 
with open('/home/bo/Desktop/test.pkl', 'wb') as f: 
    pickle.dump(o, f, 2) 

Python的2 - 做在unpickle:

import pickle 
import collections 

with open('/home/bo/Desktop/test.pkl', 'rb') as f: 
    o = pickle.load(f) 

当我这样做,我可以读o没有问题:

>>> o 
0: OrderedDict([(1, 1), (2, 2), (3, 3), (4, 4)]) 
+0

不适用于我。我想知道我在做什么不同。这里是我的Python版本: Python 2.7.6 Python 3.4.3 –

+0

你尝试我的确切代码snippets?你得到的错误表明它是一个命名空间问题,而不是一个pickle版本问题。如果你在pickle文件的源文件中从集合中导入了OrderedDict',那么对目的地执行相同的操作。 – bbayles

+0

是的,我用这个确切的代码,这里是:https://gist.github.com/mwasilew/22f78bafc707127b32a9和https://gist.github.com/mwasilew/2220b3c767af4da0e93f。这仍然给出与以前相同的错误。 –