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

为什么Python不包含从文件名加载pickle的函数?,python,pickle,Python,Pickle,我经常在Python脚本和IPython笔记本中包含这个或类似的内容 import cPickle def unpickle(filename): with open(filename) as f: obj = cPickle.load(f) return obj 这似乎是一个足够常见的用例,标准库应该提供一个做同样事情的函数。有这样的功能吗?如果没有,为什么呢?stdlib和PyPI上的大多数序列化库都有类似的API。我很确定是它设定了标准,*和pickle,

我经常在Python脚本和IPython笔记本中包含这个或类似的内容

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

这似乎是一个足够常见的用例,标准库应该提供一个做同样事情的函数。有这样的功能吗?如果没有,为什么呢?

stdlib和PyPI上的大多数序列化库都有类似的API。我很确定是它设定了标准,*和
pickle
json
PyYAML
,等等都是它的足迹

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

显然,您需要
加载
/
转储
;您无法在基于文件名的函数上构建它们,而要在基于文件对象的函数上构建它们,您需要
StringIO
,后者直到后来才出现

您不一定需要
加载
/
转储
,因为它们可以构建在
加载
/
转储
之上-但这样做可能会对性能产生重大影响:在内存中构建整个内容之前,无法将任何内容保存到文件,反之亦然,这对于大型对象来说可能是一个问题

您肯定不需要基于文件名的
loadf
/
dumpf
函数,因为这些函数可以简单地构建在
load
/
dump
之上,没有性能影响,也没有用户可能出错的棘手问题

一方面,无论如何拥有它们都很方便,而且有些库,比如
ElementTree
,确实具有类似的功能。它可能只会为每个项目节省几秒钟和几行,但将其乘以数千个项目

另一方面,它会使Python变得更大。如果将这两个功能添加到每个模块中,那么下载和安装它所需的额外1K就不多了(尽管这在1.x时代比现在意味着更多…),但更多的内容需要记录、学习和记忆。当然,每次您需要修复
marshal.dumpf
中的错误时,都需要维护更多的代码。您必须记得检查
pickle.dumpf
json.dumpf
,以确保它们不需要更改,有时您不会记得

平衡这两个因素实际上是一种判断。一个几十年前就有人做过的,从那以后可能没有人真正讨论过。如果您认为现在有很好的理由对其进行更改,您可以随时在上发布功能请求或启动线程


*不在;刚刚有
加载
转储
。Guido添加了
加载
转储
,作为主要描述为“为Mac添加单独的主程序:macmain.c”的更改的一部分。大概是因为Python解释器中的某些东西需要转储并加载到字符串**


**
marshal
被用作导入
.pyc
文件等操作的基础。这也意味着(至少在CPython中)它不仅仅是用C实现的,而是静态地内置到解释器本身的核心中。虽然我认为它实际上可以变成一个常规模块,因为3.4
import
发生了变化,但它肯定不能回到早期。所以,这是保持其小型化和简单化的额外动机。

假设您已经在其他地方导入了cPickle,其他一切都可以在一行中完成:
obj=cPickle.load(open(filename,“rb”))
@ODiogoSilva:只有在您喜欢泄漏文件描述符的情况下。显然不够普通/基本。你有没有看过什么样的函数实际上是内置的?这就像问:“为什么小鸡会过马路?”:@StefanPochmann有一些东西我不会称之为“基本的”。
str
类真的需要
expandtabs
?stdlib是否需要
SimpleHTTPServer
?很多早期的东西都是内置的,其实历史的原因比理性的原因更多;当它看起来一致时,更多的是因为Guido有很好的品味(和/或一台时间机器),而不是因为任何人都像新的变化一样在公共场合深思熟虑和争论。