我经常在Python脚本和IPython笔记本中包含这个或接近它的东西。
import cPickle
def unpickle(filename):
with open(filename) as f:
obj = cPickle.load(f)
return obj
这似乎是一个常见的用例,标准库应提供执行相同操作的功能。有这样的功能吗?如果没有,怎么回事?
答案 0 :(得分: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天比现在更多...),但更多的是文档,更多要学习,更多要记住。当然还需要维护更多代码 - 每次需要修复marshal.dumpf
中的错误时,您必须记得检查pickle.dumpf
和json.dumpf
以确保它们不需要更改,有时你不会记得。
平衡这两个考虑因素实际上是一种判断。一个人几十年前做过,可能从那时起就没有人真正讨论过。如果您认为今天更改它有一个很好的案例,您可以随时在the issue tracker上发布功能请求,或在python-ideas
上开始一个帖子。
*不在the original 1991 version of marshal.c
;只有load
和dump
。 Guido添加了loads
和dumps
in 1993作为更改的一部分,其主要描述是“为Mac添加单独的主程序:macmain.c”。大概是因为Python解释器中的某些内容需要转储并加载到字符串。 **
** marshal
用作导入.pyc
文件等内容的基础。这也意味着(至少在CPython中)它不仅在C中实现,而且静态地构建在解释器本身的核心中。虽然我认为自{3.4} import
更改以来,实际上可以变成常规模块,但它肯定不会在早期发生。所以,这是保持小而简单的额外动力。