Python序列化-为什么要泡菜?


87

我了解到,Python腌制是一种以“尊重”对象编程的方式“存储” Python对象的方法-与以txt文件或DB编写的输出不同。

您是否在以下方面有更多详细信息或参考:

  • 腌制后的物体在哪里存储?
  • 为什么酸洗保留对象表示比存储在DB中更多?
  • 如何从一个Python Shell会话中检索腌制的对象到另一个?
  • 序列化有用时,您有哪些重要示例?
  • 用pickle进行序列化是否意味着数据“压缩”?

换句话说,我正在寻找有关酸洗的文档-Python.doc解释了如何实现酸洗,但似乎没有深入探讨有关序列化的使用和必要性的细节。


我想猜测是保存状态以供以后恢复还是将对象共享/复制到其他python运行时。
synthesizerpatel

13
维基百科有关序列化的文章回答了许多问题:en.wikipedia.org/wiki/Serialization
NPE

5
您是否在问为什么我需要Pickle在Python中进行序列化?或者更确切地说,序列化的目的是什么?
moooeeeep 2012年

也许要提一下咸菜的安全性问题。例如可以在找到文档,并在许多做题,像这一个
djvg

Answers:


99

酸洗是将python对象(列表,字典等)转换为字符流的一种方法。想法是,此字符流包含在另一个python脚本中重构对象所需的所有信息。

至于腌制信息的存储位置,通常可以这样做:

with open('filename', 'wb') as f:
    var = {1 : 'a' , 2 : 'b'}
    pickle.dump(var, f)

那将把我们var字典的腌制版本存储在“文件名”文件中。然后,在另一个脚本中,您可以从该文件加载到变量中,然后重新创建字典:

with open('filename','rb') as f:
    var = pickle.load(f)

腌制的另一种用途是,如果您需要通过网络(可能是通过套接字或其他方式)传输此字典,则首先需要将其转换为字符流,然后可以通过套接字连接发送它。

同样,这里没有“压缩”可言……只是从一种表示形式(RAM中)转换为另一种表示形式(“文本”中)的一种方式。

About.com在这里对酸洗有很好的介绍。


2
通常一个人会做with open('filename') as f: ...
moooeeeep 2012年

3
此外,您将需要执行操作with open(filename, 'wb') as f: ...或无法写入文件。
Tim Pietzcker 2012年

谢谢!!关于Python持久性管理的这篇文章很好,在这里
kiriloff 2012年

1
通常,使用它pickle通过网络传输字典不是一个好主意(json可能更好)。尽管在极少数情况下它可能有用,例如multiprocessing模块。
jfs 2012年

@Tim Pietzcker:protocol=0(Python2.x上的默认设置)可用于以文本模式打开的文件。
jfs 2012年

36

酸洗对于分布式和并行计算绝对必要。

假设您要使用并行映射简化multiprocessing(或使用pyina跨群集节点),那么您需要确保要在并行资源上映射的函数会腌制。如果没有腌制,则不能将其发送到其他进程,计算机等上的其他资源。另请参见此处的示例。

为此,我使用dill,它可以序列化python中的几乎所有内容。Dill还有一些很好的工具,可以帮助您了解在代码失败时导致酸洗失败的原因。

而且,是的,人们使用选择来保存计算状态,ipython会话等。您还可以扩展泡菜的皮克勒和Unpickler会做压缩用bz2或者gzip,如果你愿意的话。


0

我发现它对于大型和复杂的自定义类特别有用。在一个特定的示例中,我想到的是(从数据库中)“收集”信息以创建类已经完成了一半。然后,用户可以在运行时更改存储在类中的信息。

您可以在数据库中拥有另一组表,并编写另一个函数来遍历存储的所有内容并将其写入新的数据库表。然后,您将需要编写另一个函数,以便能够通过读回所有信息来加载保存的内容。

另外,您可以按原样腌制整个类,然后将其存储到数据库中的单个字段中。然后,当您将其重新加载时,它将像以前一样立即全部加载回去。在保存和检索复杂的类时,这样可以节省大量时间和代码。


-1

这是一种序列化。使用cPickle它比泡菜要快得多。

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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.