提问人:kiriloff 提问时间:1/23/2012 最后编辑:agfkiriloff 更新时间:3/14/2019 访问量:56482
Python 序列化 - 为什么选择泡菜?
Python serialization - Why pickle?
问:
我知道 Python 酸洗是一种以尊重对象编程的方式“存储”Python 对象的方法 - 不同于以 txt 文件或 DB 编写的输出。
您是否对以下几点有更多详细信息或参考资料:
- 腌制物品“存放”在哪里?
- 为什么酸洗保留对象表示比存储在数据库中更重要?
- 我可以将腌制的对象从一个 Python shell 会话检索到另一个 Python shell 会话吗?
- 您是否有序列化有用的重要示例?
- 使用 Pickle 进行序列化是否意味着数据“压缩”?
换句话说,我正在寻找一个关于酸洗的文档 - Python.doc 解释了如何实现泡菜,但似乎没有深入研究有关序列化的使用和必要性的详细信息。
答:
酸洗是一种将 python 对象(列表、字典等)转换为字符流的方法。这个想法是,这个字符流包含了在另一个 python 脚本中重建对象所需的所有信息。
至于腌制信息的存储位置,通常可以:
with open('filename', 'wb') as f:
var = {1 : 'a' , 2 : 'b'}
pickle.dump(var, f)
这会将我们的 dict 的腌制版本存储在“filename”文件中。然后,在另一个脚本中,你可以从这个文件加载到一个变量中,然后重新创建字典:var
with open('filename','rb') as f:
var = pickle.load(f)
酸洗的另一个用途是,如果你需要通过网络传输这个字典(也许用套接字或其他东西)。您首先需要将其转换为字符流,然后可以通过套接字连接发送它。
另外,这里没有“压缩”可言......它只是一种从一种表示(在RAM中)转换为另一种表示(在“文本”中)的方法。
About.com 在这里对酸洗有一个很好的介绍。
评论
with open('filename') as f: ...
with open(filename, 'wb') as f: ...
pickle
multiprocessing
protocol=0
酸洗对于分布式和并行计算是绝对必要的。
假设你想用(或用pyina跨集群节点)做一个并行map-reduce,那么你需要确保你想在并行资源之间映射的函数会变质。如果它没有腌制,你就不能把它发送到另一个进程、计算机等上的其他资源。另请参阅此处的一个很好的示例。multiprocessing
为此,我使用 dill,它几乎可以序列化 python 中的任何内容。Dill 也有一些很好的工具,可以帮助你了解在代码失败时导致酸洗失败的原因。
而且,是的,人们使用拾取来保存计算的状态,或者您的 ipython 会话,或者其他什么。您还可以扩展 pickle 的 Pickler 和 UnPickler 以根据需要进行压缩。bz2
gzip
这是一种序列化。使用 cPickle,它比 pickle 快得多。
import pickle
##make Pickle File
with open('pickles/corups.pickle', 'wb') as handle:
pickle.dump(corpus, handle)
#read pickle file
with open('pickles/corups.pickle', 'rb') as handle:
corpus = pickle.load(handle)
评论
我发现它对大型和复杂的自定义类特别有用。在我正在考虑的一个特定示例中,“收集”信息(从数据库中)以创建类已经成功了一半。然后,存储在类中的信息可能会在运行时由用户更改。
您可以在数据库中拥有另一组表,并编写另一个函数来遍历存储的所有内容并将其写入新的数据库表。然后,您需要编写另一个函数,以便能够加载通过重新读取所有这些信息来保存的内容。
或者,您可以按原样对整个类进行酸洗,然后将其存储到数据库中的单个字段中。然后,当您将其加载回去时,它将像以前一样立即加载回来。在保存和检索复杂类时,这最终可以节省大量时间和代码。
评论