文件——存储原生的Python对象:pickle

未匹配的标注

如前面代码中展示的,使用 eval 将字符串转换为对象,是一个强大的工具。事实上,有时它强大了。eval将很开心地运行任何Python表达式——即使一个可能删除电脑上所有文件的表达式,假如有必要的权限!如果真的想存储原生的Python对象,但又不能信任文件中的数据源,Python的标准库 pickle模块就很理想。

pickle模块是一个更高级的工具,允许直接将几乎任何Python对象存储在文件中,而对我们没有与字符串进行来回转换的要求。它就像一个超级通用的数据格式化和解析实用程序。比如,要存储字典在文件中,直接对它序列化:

>>> D = {'a': 1, 'b': 2}
>>> F = open('datafile.pkl', 'wb')
>>> import pickle
>>> pickle.dump(D, F) # Pickle any object to file
>>> F.close()

然后,随后要取回字典,简单地再次使用 pickle来创建它:

>>> F = open('datafile.pkl', 'rb')
>>> E = pickle.load(F) # Load any object from file
>>> E
{'a': 1, 'b': 2}

我们取回了一个等价的字典对象,不需要手动分割或转换。pickle模块执行了所谓的对象序列号——将对象与字节字符串相互转换——但对我们来说只需要很少的工作。事实上,pickle在内部将字典转换为字符串形式,虽然没有什么好看的(而且如果在其它的数据协议模式下序列化,可能会有所不同):

>>> open('datafile.pkl', 'rb').read() # Format is prone to change!
b'\x80\x03}q\x00(X\x01\x00\x00\x00bq\x01K\x02X\x01\x00\x00\x00aq\x02K\
x01u.'

因为 pickle 可以从这个格式重建对象,所以无需亲自处理它。要获取更多关于 pickle模块的信息,请参见Python标准库手册,或交互式地导入 pickle 然后把它传递给 help。当探索时,还要看一下 shelve 模块。shelve是一个工具,它使用pickle 把Python对象存储在一个按键访问的文件系统中,这超过了这里的范围(虽然在第28章会看到一个 shelve的实例,在第31第37章还有其它 pickle例子)。


注意

注意我以二进制模式打开用来存储序列化对象的文件;二进制模式在Python 3.X 总是需要的,因为 pickler(译注:help(pickle) 可以看到 pickler 是一个类,它有一个Pickler的方法) 创建并使用一个字节字符串对象,且这些对象意味着二进制模式的文件(文本模式文件在3.X中意味着 str字符串)。在更早的Python中,可以为 protocol 0(默认值,它创建了ASCII文本)使用文本模式文件),只要文本模式被一致地使用;更高的protocol需要二进制模式文件。Python 3.X的默认 protocol 是3(二进制),但即使对 protocol 0它也创建 bytes。参见第28第31第37章;Python的库手册;或参考书获取更多关于序列化数据的知识和例子。

Python 2.X also has a cPickle module, which is an optimized version of pickle that can be imported directly for speed. Python 3.X 将此模块重命名为 _pickle 并在 pickle中自动使用它——脚本简单地导入 pickle 然后让Python优化它。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~