如何使用泡菜保存字典?


370

我已经仔细阅读了Python文档提供的信息,但仍然有些困惑。有人可以张贴示例代码来编写新文件,然后使用pickle将字典转储到其中吗?


5
阅读以下内容:doughellmann.com/PyMOTW/pickle,并在需要特定问题时回来
pyfunc 2012年

2
-1请参阅以前的评论。尝试一下。然后,如果它不起作用(并非总是如此),则可以提出一个有针对性的问题(连同一个或两个可以检验的假设,并“查询”,可能在向其他人提问之前)。例如,是否存在语法错误?有例外吗 价值观又变乱了吗?

1
我一直试图用它来保存pygame的信息。我使用了上面的信息,我的代码如下所示:
Chachmu 2012年

名称= raw_input('输入文件名:')tf =打开(name +'。pkl','wb')pickle.dump(total,tf)tf.close()
Chachmu 2012年

2
您应该问一个有关如何腌制表面物体的新问题
John La Rooy

Answers:


727

尝试这个:

import pickle

a = {'hello': 'world'}

with open('filename.pickle', 'wb') as handle:
    pickle.dump(a, handle, protocol=pickle.HIGHEST_PROTOCOL)

with open('filename.pickle', 'rb') as handle:
    b = pickle.load(handle)

print a == b

4
@houbysoft:为什么要删除pickle.HIGHEST_PROTOCOL
Blender

37
@Blender:与这个级别的问题无关且不必要地复杂-默认设置对于普通用户来说很好。
houbysoft '16

28
@houbysoft:对于Python 3用户而言是正确的,但是在Python 2上,使用默认协议(0)不仅在时间和空间上效率低下,而且实际上不能处理协议2+可以很好处理的许多事情(例如,新的样式的类__slots__)。我并不是说您应该始终使用HIGHEST_PROTOCOL,但是确保您不使用协议0或1实际上很重要。
ShadowRanger

11
什么是pickle.HIGHEST_PROTOCOL真正做到?
BallpointBen

7
@BallpointBen:它将选择您的Python版本支持的最高协议版本:docs.python.org/3/library/pickle.html#data-stream-format
Blender

92
import pickle

your_data = {'foo': 'bar'}

# Store data (serialize)
with open('filename.pickle', 'wb') as handle:
    pickle.dump(your_data, handle, protocol=pickle.HIGHEST_PROTOCOL)

# Load data (deserialize)
with open('filename.pickle', 'rb') as handle:
    unserialized_data = pickle.load(handle)

print(your_data == unserialized_data)

的优点HIGHEST_PROTOCOL是文件变小。这使得脱皮有时更快。

重要提示:泡菜的最大文件大小约为2GB。

替代方式

import mpu
your_data = {'foo': 'bar'}
mpu.io.write('filename.pickle', data)
unserialized_data = mpu.io.read('filename.pickle')

替代格式

对于您的应用程序,以下内容可能很重要:

  • 其他编程语言的支持
  • 阅读/写作表现
  • 紧凑度(文件大小)

另请参阅:数据序列化格式的比较

如果您想寻找一种制作配置文件的方法,则可能需要阅读我的短文《Python中的配置文件》。


1
我认为2GB的限制已在protocol = 4或更高版本下删除。
ComputerScientist

28
# Save a dictionary into a pickle file.
import pickle

favorite_color = {"lion": "yellow", "kitty": "red"}  # create a dictionary
pickle.dump(favorite_color, open("save.p", "wb"))  # save it into a file named save.p

# -------------------------------------------------------------
# Load the dictionary back from the pickle file.
import pickle

favorite_color = pickle.load(open("save.p", "rb"))
# favorite_color is now {"lion": "yellow", "kitty": "red"}

1
有必要在open()之后使用close()吗?
PlsWork '18

1
是的,一般而言。但是在CPython(您可能拥有的默认python)中,只要文件对象过期(没有任何引用),该文件就会自动关闭。在这种情况下,由于open()返回后没有任何文件对象引用,因此一旦负载返回,它将被关闭。不认为这是一种好习惯,并且会在其他系统上引起问题
Ankur S

14

通常,dict除非仅包含简单的对象(例如字符串和整数),否则酸洗a 将失败。

Python 2.7.9 (default, Dec 11 2014, 01:21:43) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from numpy import *
>>> type(globals())     
<type 'dict'>
>>> import pickle
>>> pik = pickle.dumps(globals())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
    Pickler(file, protocol).dump(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 306, in save
    rv = reduce(self.proto)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle module objects
>>> 

即使是非常简单的方法dict也会经常失败。它仅取决于内容。

>>> d = {'x': lambda x:x}
>>> pik = pickle.dumps(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
    Pickler(file, protocol).dump(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 748, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <function <lambda> at 0x102178668>: it's not found as __main__.<lambda>

但是,如果使用更好的序列化器(例如dill或)cloudpickle,则可以对大多数词典进行腌制:

>>> import dill
>>> pik = dill.dumps(d)

或者,如果您想将dict文件保存到文件中...

>>> with open('save.pik', 'w') as f:
...   dill.dump(globals(), f)
... 

后一个示例与此处发布的任何其他好的答案相同(除了忽略商品内容的可腌性之外dict)。


9
>>> import pickle
>>> with open("/tmp/picklefile", "wb") as f:
...     pickle.dump({}, f)
... 

通常,最好使用cPickle实现

>>> import cPickle as pickle
>>> help(pickle.dump)
Help on built-in function dump in module cPickle:

dump(...)
    dump(obj, file, protocol=0) -- Write an object in pickle format to the given file.

    See the Pickler docstring for the meaning of optional argument proto.

6

如果您只想将字典存储在单个文件中,请pickle像这样使用

import pickle

a = {'hello': 'world'}

with open('filename.pickle', 'wb') as handle:
    pickle.dump(a, handle)

with open('filename.pickle', 'rb') as handle:
    b = pickle.load(handle)

如果要在多个文件中保存和还原多个词典以进行缓存和存储更复杂的数据,请使用anycache。它可以完成您需要的所有其他工作pickle

from anycache import anycache

@anycache(cachedir='path/to/files')
def myfunc(hello):
    return {'hello', hello}

Anycache myfunc根据不同文件的参数存储不同的结果,cachedir然后重新加载它们。

有关更多详细信息,请参见文档


6

将Python数据(例如字典)转储到pickle文件的简单方法。

import pickle

your_dictionary = {}

pickle.dump(your_dictionary, open('pickle_file_name.p', 'wb'))

3
import pickle

dictobj = {'Jack' : 123, 'John' : 456}

filename = "/foldername/filestore"

fileobj = open(filename, 'wb')

pickle.dump(dictobj, fileobj)

fileobj.close()

-8

我发现酸洗令人困惑(可能是因为我很胖)。我发现这可行,但是:

myDictionaryString=str(myDictionary)

然后可以将其写入文本文件。我遇到错误并告诉我将整数写入.dat文件时,我放弃尝试使用pickle。很抱歉没有使用泡菜。


1
-1:应按原样保存它(即python对象),以便我们以后可以阅读它,而无需花费大量时间等待再次运行它。Pickle允许我们存储一个python对象供以后阅读。
Catbuilts '18 -10-5

这是在“低质量帖子”队列中返回的旧答案。这不是一个不好的解决方案,因为它可能适用于非常简单的词典,但是dict对于包含更多深度的对象(可以仅通过以下方式打印)是非常合理的:名称)和/或没有任何或完整字符串表示形式的对象。
ti7

1
为了补充@ ti7的观点,无论答案的技术优点如何,这篇文章都不是VLQ。如果有人认为此答案不正确,则应投下反对票和/或评论解释原因,而不是将其标记为VLQ。
EJoshuaS-恢复莫妮卡
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.