首页 > 解决方案 > 从 Python 2 加载 Python 3 泡菜

问题描述

我有一个在 python 2 中创建的泡菜文件(我不知道究竟是如何创建的)。它打算由以下 python 2 行加载,当在 python 3 中使用时(不出所料)不起作用:

with open('filename','r') as f:
    foo, bar = pickle.load(f)

结果:

“ascii”编解码器无法解码位置 1219 中的字节 0xc2:序数不在范围内(128)

手动检查文件表明它是 utf-8 编码的,因此:

with open('filename','r', encoding='utf-8') as f:
    foo, bar = pickle.load(f)

结果:

TypeError:需要一个类似字节的对象,而不是“str”

使用二进制编码:

with open('filename','rb', encoding='utf-8') as f:
    foo, bar = pickle.load(f)

结果:

ValueError:二进制模式不采用编码参数

没有二进制编码:

with open('filename','rb') as f:
    foo, bar = pickle.load(f)

结果:

UnpicklingError: 无效的加载键,' '。

这个泡菜文件刚刚坏了吗?如果没有,我怎样才能在 python 3 中撬开这个东西?(我浏览了广泛的相关问题集合,但还没有找到任何可行的方法。)

最后,注意原文

将 cPickle 导入为泡菜

已被替换为

将 _pickle 导入为泡菜

标签: python-3.xpython-2.7pickle

解决方案


可以使用 pickle.load 函数中的fix_imports参数帮助在 python3(本例中为版本 3.7.2)中加载 python2 pickle ,但在我的情况下,它也可以在不将该参数设置为 True 的情况下工作。

我试图加载使用 Python2 生成的 pickle 中包含的 scipy.sparse.csr.csr_matrix。

使用 UNIX 命令文件检查文件格式时,它会显示:

>file -bi python2_generated.pckl
application/octet-stream; charset=binary

我可以使用以下代码在 Python3 中加载泡菜:

with open("python2_generated.pckl", "rb") as fd:
    bh01 = pickle.load(fd, fix_imports=True, encoding="latin1")

请注意,无论是否将 fix_imports 设置为 True,加载都是成功的 至于“latin1”编码,pickle.load函数的 Python3 文档(版本 3.7.2)说:Using encoding='latin1' is required for unpickling NumPy arrays以及 Python 2 腌制的日期时间、日期和时间的实例

虽然这专门用于 scipy 矩阵(或 Numpy 数组),并且由于 Novak 没有澄清他的 pickle 文件包含的内容,但我希望这对其他用户有所帮助:)


推荐阅读