为什么Python不包含从文件名加载pickle的函数?

时间:2015-05-07 23:29:35

标签: python pickle

我经常在Python脚本和IPython笔记本中包含这个或接近它的东西。

import cPickle
def unpickle(filename):
    with open(filename) as f:
        obj = cPickle.load(f)
    return obj

这似乎是一个常见的用例,标准库应提供执行相同操作的功能。有这样的功能吗?如果没有,怎么回事?

1 个答案:

答案 0 :(得分:9)

stdlib和PyPI上的大多数序列化库都有类似的API。我很确定marshal设置了标准, * picklejsonPyYAML等等。它的脚步。

所以,问题是,marshal为什么这样设计?

嗯,你显然需要loads / dumps;你无法在基于文件名的函数之上构建它们,并且在基于文件对象的函数之上构建它们,你需要StringIO,直到后来才会这样。

您不一定需要 load / dump,因为这些可以构建在loads / dumps之上 - 但是因此可能会产生重大的性能影响:在内存中构建整个内容之前,不能将任何内容保存到文件中,反之亦然,这可能是大型对象的问题。

您绝对不需要基于文件名的loadf / dumpf功能,因为这些功能可以在load / dump之上轻松构建,但没有性能影响,并没有用户可能会出错的棘手问题。

一方面,无论如何都可以方便地使用它们 - 并且有一些库,例如ElementTree,它们具有类似的功能。它可能只会为每个项目节省几秒钟和几行,但会将其乘以数千个项目......

另一方面,它会使Python更大。如果你将这两个功能添加到每个模块中,那么额外的1K就可以下载和安装它(虽然这确实意味着在1.x天比现在更多...),但更多的是文档,更多要学习,更多要记住。当然还需要维护更多代码 - 每次需要修复marshal.dumpf中的错误时,您必须记得检查pickle.dumpfjson.dumpf以确保它们不需要更改,有时你不会记得。

平衡这两个考虑因素实际上是一种判断。一个人几十年前做过,可能从那时起就没有人真正讨论过。如果您认为今天更改它有一个很好的案例,您可以随时在the issue tracker上发布功能请求,或在python-ideas上开始一个帖子。

*不在the original 1991 version of marshal.c;只有loaddump。 Guido添加了loadsdumps in 1993作为更改的一部分,其主要描述是“为Mac添加单独的主程序:macmain.c”。大概是因为Python解释器中的某些内容需要转储并加载到字符串。 **

** marshal用作导入.pyc文件等内容的基础。这也意味着(至少在CPython中)它不仅在C中实现,而且静态地构建在解释器本身的核心中。虽然我认为自{3.4} import更改以来,实际上可以变成常规模块,但它肯定不会在早期发生。所以,这是保持小而简单的额外动力。