在Python 3中打开Python 2的Pickle文件时出现TypeError: a bytes-like object is required, not 'str'错误。

8

我正在尝试使用在Python 2中有效的代码打开一个pickle文件,但现在却出现了错误。以下是代码:

with open(file, 'r') as f:
    d = pickle.load(f)

TypeError                                 Traceback (most recent call last)
<ipython-input-25-38f711abef06> in <module>()
      1 with open(file, 'r') as f:
----> 2     d = pickle.load(f)

TypeError: a bytes-like object is required, not 'str'

我在其他SO答案中看到,当使用open(file ,'rb')时人们会遇到这个问题,而切换到open(file ,'r')则可以解决。如果有帮助的话,我为了实验尝试了open(file ,'rb'),但是得到了以下错误:

UnpicklingError                           Traceback (most recent call last)
<ipython-input-26-b77842748a06> in <module>()
      1 with open(file, 'rb') as f:
----> 2     d = pickle.load(f)

UnpicklingError: invalid load key, '\x0a'.

当我使用f = open(file, 'r')打开文件并输入f时,我会得到以下结果:

<_io.TextIOWrapper name='D:/LargeDataSets/Enron/final_project_dataset.pkl' mode='r' encoding='cp1252'>

所以我也尝试了:

with open(file, 'rb') as f:
    d = pickle.load(f, encoding='cp1252')

使用 'rb' 仍然出现了相同的错误:

UnpicklingError                           Traceback (most recent call last)
<ipython-input-27-959b1b0496d0> in <module>()
      1 with open(file, 'rb') as f:
----> 2     d = pickle.load(f, encoding='cp1252')

UnpicklingError: invalid load key, '\x0a'.
3个回答

15

使用编码为bytes的方式加载的解释。

假设你有一个需要在 Python2 中进行 pickle 序列化的字典。

data_dict= {'key1': value1, 'key2': value2}
with open('pickledObj.pkl', 'wb') as outfile:
  pickle.dump(data_dict, outfile)

Python3 中的反序列化

with open('pickledObj.pkl', 'rb') as f:
        data_dict = pickle.load(f, encoding='bytes')

注意:字典的键不再是字符串,而是字节。

data_dict['key1'] #result in KeyError

data_dict[b'key1'] #gives value1

或使用

data_dict['key1'.encode('utf-8')] #gives value1

这也将value字符串转换为字节!如何确保向后兼容性? - Gulzar

2

是的,Python 2和3的pickle格式之间有一些变化。如果可能的话,我建议使用Python 3重新创建pickled数据。

如果不可能或不容易实现,可以尝试使用不同的编码设置(你尝试过'utf8'吗?)或者按照这里所述使用encoding='bytes'读取数据,然后在代码中解码字符串以进一步检查对象。


-1

在Sublime中查看原始文件后,似乎该文件没有正确地进行pickle。上述代码在另一个版本的该文件上完美运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接