python3 中的 _pickle 不适用于大数据保存

Posted

技术标签:

【中文标题】python3 中的 _pickle 不适用于大数据保存【英文标题】:_pickle in python3 doesn't work for large data saving 【发布时间】:2015-06-24 14:18:37 【问题描述】:

我正在尝试应用_pickle 将数据保存到磁盘上。但是调用_pickle.dump的时候报错了

OverflowError: cannot serialize a bytes object larger than 4 GiB

这是使用_pickle 的硬性限制吗? (cPickle 用于 python2)

【问题讨论】:

【参考方案1】:

是的,这是一个硬编码限制;来自save_bytes function:

else if (size <= 0xffffffffL) 
    // ...

else 
    PyErr_SetString(PyExc_OverflowError,
                    "cannot serialize a bytes object larger than 4 GiB");
    return -1;          /* string too large */

协议使用 4 个字节将对象的大小写入磁盘,这意味着您最多只能跟踪 232 == 4GB 的大小。

如果您可以将bytes 对象分解为多个对象,每个对象小于 4GB,当然您仍然可以将数据保存到 pickle 中。

【讨论】:

谢谢!是否可以将大文件保存在磁盘上并绕过此限制? @Jake0x32:不带泡菜;这是协议中的硬限制。将您的 bytes 对象分解成更小的部分。 @MartijnPieters 我在尝试腌制分类器from sklearn.svm import SVC 时遇到了同样的问题。我如何将对象分解成字节然后腌制?【参考方案2】:

在具有 PE​​P 3154 和 Pickle 4.0 的 Python 3.4 中不再存在https://www.python.org/dev/peps/pep-3154/

但你需要说你要使用第 4 版协议:https://docs.python.org/3/library/pickle.html

pickle.dump(d, open("file", 'w'), protocol=4)

【讨论】:

这样打开文件是不是好办法?我的意思是不关闭它。 @1a1a11a 最好使用“with”语句打开文件以确保文件关闭。但是,一旦调用 pickle.dump 返回,对文件对象的引用计数就会下降到零,因此它会立即进行垃圾收集,并且无论如何都会关闭文件。 @jlund3 谢谢。我已经想知道如果 Python 有垃圾收集器,“with”到底是什么用途。我猜这都是关于范围界定的。【参考方案3】:

对于为什么泡菜不起作用,上面有一个很好的答案。 但它仍然不适用于 Python 2.7,这是一个问题 如果你还在 Python 2.7 并且想要支持大 文件,尤其是 NumPy(超过 4G 的 NumPy 数组失败)。

您可以使用 OC 序列化,该序列化已更新为适用于数据 4G。有一个 Python C 扩展模块可从:

http://www.picklingtools.com/Downloads

查看文档:

http://www.picklingtools.com/html/faq.html#python-c-extension-modules-new-as-of-picklingtools-1-6-0-and-1-3-3

但是,这里有一个简短的总结:有 ocdumps 和 ocloads,非常像 pickle 的转储和加载::

from pyocser import ocdumps, ocloads
ser = ocdumps(pyobject)   : Serialize pyobject into string ser
pyobject = ocloads(ser)   : Deserialize from string ser into pyobject

OC 序列化速度提高了 1.5-2 倍,并且还可以与 C++ 一起使用(如果您正在混合语言)。它适用于所有内置类型,但不适用于类 (部分是因为它是跨语言的,而且很难构建 C++ 类 来自 Python)。

【讨论】:

以上是关于python3 中的 _pickle 不适用于大数据保存的主要内容,如果未能解决你的问题,请参考以下文章

为什么此代码不适用于大数?

python3 中的Json与Pickle

Python3中pickle模块介绍

python3 jason & pickle

不适用于python中的代码datetime.strptime

Python3 从零单排9_json&pickle&shelve