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

DGr*_*ady 6 python pickle

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

import cPickle
def unpickle(filename):
    with open(filename) as f:
        obj = cPickle.load(f)
    return obj
Run Code Online (Sandbox Code Playgroud)

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

aba*_*ert 9

stdlib和PyPI上的大多数序列化库都有类似的API.我敢肯定,这是marshal该设置标准,*pickle,json,PyYAML等方面都只是跟着它的脚步.

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

好吧,你显然需要loads/ dumps; 你不能在基于文件名的函数之上构建它们,并在你需要的基于文件对象的函数之上构建它们,StringIO直到后来才能实现.

你不一定需要 load/dump,因为那些可以构建在loads/ 之上dumps- 但是这样做可能会产生重大的性能影响:在内存中构建整个内容之前,你无法将任何内容保存到文件中,并且反之亦然,这可能是巨大物体的问题.

你绝对不需要loadf/ dumpf基于文件名功能,因为这些可以平凡之上建立load/ dump,没有性能影响,并没有取巧的考虑,用户有可能得到错误的.

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

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

平衡这两个考虑因素实际上是一种判断力.一个人几十年前做过,可能从那时起就没有人真正讨论过.如果您认为今天更改它有一个很好的案例,您可以随时在问题跟踪器上发布功能请求或启动线程python-ideas.


*不是原来的1991年版marshal.c ; 那只是loaddump.Guido 在1993年添加loads并作为更改的一部分,其主要描述是"为Mac添加单独的主程序:macmain.c".大概是因为Python解释器中的某些东西需要转储并加载到字符串.**dumps

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