我在 python3 中使用协议 3 腌制了文件,现在我需要使用 python2 取消腌制它们,我该怎么办?

I have pickled files using protocol 3 in python3, and now I need to unpickle them with python2, what can I do?

mydata = pickle.load(myfile, "rb")
ValueError: unsupported pickle protocol: 3

这与:ValueError: unsupported pickle protocol: 3, python2 pickle can not load the file dumped by python 3 pickle?

相关

很明显,有先见之明,如果你想用 python2 解开 pickle 文件,你必须在将 pickle 文件转储到 python3 时设置 protocol=2

但是,如果您不幸遇到了在 python 3 中使用协议 3 腌制的文件,现在您必须使用 python2 读取它们怎么办?有什么解决方法吗?

有一个相关问题,但似乎是另一个核心问题:unpickle OrderedDict from python3 in python2

如果您无法控制这些腌制文件的创建方式,并且您必须将它们加载到 Python 2.7 中,那么 不幸的是不是简单的解决方法。

也许创建文件的人不知道 Python 3 中 pickle 的默认协议是“3”,但这是 backward-incompatible。

来自 documentation

Currently the default protocol is 3; a backward-incompatible protocol designed for Python 3.0.

如果它们是一组固定的文件,那么解决方法可能是编写一个脚本,在 Python 3.0 中迭代加载协议 3 腌制文件,然后使用 [=10] re-writes 它们=] 作为 one-shot 修复。然后您将能够在 Python 2.7 中阅读它们。如果将来要创建您的代码需要处理的文件,还要确保修改编写这些文件的原始代码。

@Kay 指出这个解决方案在实践中是多么简单:

As easy as pickle.dump(pickle.load(sys.stdin), sys.stdout, 2)

最简单和最简单的方法是编写一个 Python3 脚本,使用协议 3 解开所有内容,然后使用协议 2 再次对其进行重新选择。(考虑同时切换到 camel。)

在Python 3:

pickle.dump(pickle.load(sys.stdin), sys.stdout, 2)

然后在 Python 2:

pickle.load(...) # This will work now in Python 2.