ChatGPT解决这个技术问题 Extra ChatGPT

如何使用 pickle 保存字典(或任何其他 Python 对象)?

我已经查看了 Python docs 提供的信息,但我仍然有点困惑。有人可以发布示例代码来编写一个新文件,然后使用 pickle 将字典转储到其中吗?

通读此内容:doughellmann.com/PyMOTW/pickle 并在您需要特定问题时回来

C
CryptoFool

尝试这个:

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)

上述解决方案没有特定于 dict 对象的任何内容。这种相同的方法将适用于许多 Python 对象,包括任意类的实例和任意复杂的数据结构嵌套。例如,用这些行替换第二行:

import datetime
today = datetime.datetime.now()
a = [{'hello': 'world'}, 1, 2.3333, 4, True, "x", 
     ("y", [[["z"], "y"], "x"]), {'today', today}]

也会产生 True 的结果。

有些物体由于其性质而不能腌制。例如,腌制包含打开文件句柄的结构是没有意义的。


@houbysoft:为什么要删除 pickle.HIGHEST_PROTOCOL
@Blender:对于这一级别的问题来说,无关紧要且不必要的复杂——普通用户使用默认设置就可以了。
@houbysoft:对于 Python 3 用户来说是正确的,但在 Python 2 上,使用默认协议 (0) 不仅在时间和空间上效率极低,而且它实际上不能处理协议 2+ 处理得很好的许多事情(例如 new -style 使用 __slots__ 的类)。我并不是说您应该始终使用 HIGHEST_PROTOCOL,但确保您不使用协议 0 或 1 实际上相当重要。
pickle.HIGHEST_PROTOCOL 实际上是做什么的?
@BallpointBen:它会选择您的 Python 版本支持的最高协议版本:docs.python.org/3/library/pickle.html#data-stream-format
M
Martin Thoma
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 的优点是文件变小了。这使得解酸有时更快。

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

替代方式

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

替代格式

CSV:超级简单的格式(读写)

JSON:非常适合编写人类可读的数据;非常常用(读写)

YAML:YAML 是 JSON 的超集,但更易于阅读(读写,JSON 和 YAML 的比较)

pickle:一种 Python 序列化格式(读写)

MessagePack(Python 包):更紧凑的表示(读写)

HDF5(Python 包):适用于矩阵(读写)

XML: 也存在 *sigh* (读 & 写)

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

其他编程语言的支持

读/写性能

紧凑性(文件大小)

另请参阅:Comparison of data serialization formats

如果您正在寻找一种制作配置文件的方法,您可能需要阅读我的短文 Configuration files in Python


我认为使用协议 = 4 或更高版本删除了 2GB 限制。
为什么是 wb 而不是 w+
n
nietaki
# 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"}

是否有必要在 open() 之后使用 close()?
是的,一般来说。然而,在 CPython(您可能拥有的默认 python)中,只要文件对象过期(当没有引用它时),文件就会自动关闭。在这种情况下,由于 open() 返回后没有引用文件对象,因此一旦 load 返回,它将关闭。这不是好的做法,会导致其他系统出现问题
为什么是 wb 而不是 w+
M
Mike McKerns

通常,腌制 dict 会失败,除非您在其中只有简单的对象,例如字符串和整数。

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>

但是,如果您使用像 dillcloudpickle 这样更好的序列化程序,那么大多数字典都可以腌制:

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

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

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

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


g
ghchoi

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

import pickle

your_dictionary = {}

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

为什么是 wb 而不是 w+
J
John La Rooy
>>> 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.

为什么是 wb 而不是 w+
c
c0fec0de

如果您只想将字典存储在单个文件中,请像这样使用 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 根据 cachedir 中不同文件的参数存储不同的 myfunc 结果并重新加载它们。

有关更多详细信息,请参阅 documentation


为什么是 wb 而不是 w+
G
George Sotiropoulos

仅供参考,熊猫现在有一种保存泡菜的方法。

我觉得更容易。

pd.to_pickle(object_to_save,'/temp/saved_pkl.pickle' )

N
Nunser
import pickle

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

filename = "/foldername/filestore"

fileobj = open(filename, 'wb')

pickle.dump(dictobj, fileobj)

fileobj.close()

g
gench

如果您想在不打开文件的情况下在一行中处理写入或读取:

  import joblib

  my_dict = {'hello': 'world'}

  joblib.dump(my_dict, "my_dict.pickle") # write pickle file
  my_dict_loaded = joblib.load("my_dict.pickle") # read pickle file

这是无关紧要的,因为在这种情况下 OP 没有询问缓存。
P
Pedro Rhian

我发现腌制令人困惑(可能是因为我很厚)。不过,我发现这行得通:

myDictionaryString=str(myDictionary)

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


-1:应该按原样保存它(即,一个python对象),以便我们稍后可以阅读它,而无需等待数小时再次运行它。 Pickle 允许我们存储一个 python 对象以供以后读取。
这是在低质量帖子队列中返回的旧答案。这不是一个糟糕的解决方案,因为它可能适用于非常简单的字典,但 dict 包含更多深度的对象是非常合理的(可能是仅按名称打印)和/或没有任何或完整字符串表示的对象。
为了补充@ti7 的观点,无论答案的技术优点如何,这篇文章都不是 VLQ。如果有人觉得这个答案不准确,他们应该投票和/或评论解释原因,而不是将其标记为 VLQ。