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

Posted

技术标签:

【中文标题】我在 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? 【发布时间】:2016-04-06 21:07:09 【问题描述】:
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 文件转储到 python3 时设置protocol=2

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

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

【问题讨论】:

协议记录在 PEP 中。如果它不使用需要 Python 3 的自定义类,那么您可以轻松地自己实现它。 【参考方案1】:

如果您无法控制这些腌制文件的创建方式,并且您必须在 Python 2.7 中加载它们,那么很遗憾没有简单的解决方法。

也许创建文件的人不知道 Python 3 中 pickle 的默认协议是“3”这一事实,但这是向后不兼容的。

来自documentation:

目前默认协议为 3;为 Python 3.0 设计的向后不兼容的协议。

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

@Kay 指出这个解决方案在实践中是多么简单:I have pickled files using protocol 3 in python3, and now I need to unpickle them with python2, what can I do?

就像pickle.dump(pickle.load(sys.stdin), sys.stdout, 2)一样简单

【讨论】:

【参考方案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.

【讨论】:

正确答案,IMO。就像pickle.dump(pickle.load(sys.stdin), sys.stdout, 2) 一样简单

以上是关于我在 python3 中使用协议 3 腌制了文件,现在我需要用 python2 解压缩它们,我该怎么办?的主要内容,如果未能解决你的问题,请参考以下文章

在 python 3.6+ 和 PyQt5 中腌制一个 QPolygon

在腌制字典中检索单个对象的问题(Python 3)

如何在 Python 3 中腌制和取消腌制到可移植字符串

多处理,Python3,Windows:TypeError:无法腌制 _thread.lock 对象

pickle.dump(模型,pickle_out)| TypeError:无法腌制 _thread._local 对象

腌制具有 __slots__ 的冻结数据类