Как я могу использовать рассол, чтобы сохранить дикт?


371

Я просмотрел информацию, которую предоставляют документы по Python , но я все еще немного сбит с толку. Может ли кто-нибудь опубликовать пример кода, который напишет новый файл, а затем с помощью pickle поместит в него словарь?


5
Прочитайте это: doughellmann.com/PyMOTW/pickle и возвращайтесь, когда вам нужен конкретный вопрос
pyfunc

2
-1 Смотрите предыдущие комментарии. Попробуй это. Затем, если это не сработало (это не всегда), можно сформулировать направленный вопрос (вместе с одной или двумя гипотезами, которые можно проверить и «запросить», возможно, перед тем, как задавать вопрос другим людям). Например, была ли синтаксическая ошибка? Исключение? Вернулись ли значения искаженными?

1
Я пытался использовать это, чтобы сохранить информацию из Pygame. Я использовал приведенную выше информацию, и мой код выглядит так:
Chachmu

name = raw_input ('имя входного файла:') tf = open (name + '. pkl', 'wb') pickle.dump (total, tf) tf.close ()
Chachmu

2
Вы должны задать новый вопрос о том, как засолить поверхностные объекты
Джон Ла Рой

Ответы:


729

Попробуй это:

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?
Блендер

37
@Blender: неуместен и излишне сложен для этого уровня вопроса - средний пользователь будет в порядке с настройками по умолчанию.
Houbysoft

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том, что файлы становятся меньше. Это делает процесс маринования иногда намного быстрее.

Важное замечание : максимальный размер файла рассола составляет около 2 ГБ.

Альтернативный способ

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

Альтернативные форматы

Для вашего приложения может быть важно следующее:

  • Поддержка другими языками программирования
  • Чтение / запись производительности
  • Компактность (размер файла)

Смотрите также: Сравнение форматов сериализации данных

Если вы предпочитаете создавать файлы конфигурации, вы можете прочитать мою короткую статью Файлы конфигурации в Python


1
Я думаю, что ограничение 2 ГБ было удалено с протоколом = 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
необходимо ли использовать close () после open ()?
PlsWork

1
Да в общем. Однако в CPython (Python по умолчанию, который у вас, вероятно, есть) файл автоматически закрывается всякий раз, когда истекает срок действия файлового объекта (когда на него ничего не ссылается). В этом случае, поскольку ничто не ссылается на объект файла после того, как он был возвращен open (), он будет закрыт, как только вернется загрузка. Это не считается хорошей практикой и приведет к проблемам в других системах
Ankur S

14

Как правило, выбор a 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>

Однако, если вы используете лучший сериализатор, такой как 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

Если вы просто хотите сохранить dict в одном файле, используйте 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)

Который вы можете записать в текстовый файл. Я прекратил попытки использовать pickle, так как получал ошибки, говорящие мне записать целые числа в файл .dat. Я извиняюсь за то, что не использовал рассол.


1
-1: следует сохранить его как есть (т. Е. Объект python), чтобы мы могли прочитать его позже, не дожидаясь часов, чтобы запустить его снова. Pickle позволяет нам хранить объект python для чтения позже.
Catbuilts

Это старый ответ, возвращающийся в очередь сообщений низкого качества. Это неплохое решение, так как оно, вероятно, работает для очень простых словарей, но очень разумно, чтобы dictв нем содержалась дополнительная глубина объектов (которые могут быть напечатаны просто name) и / или объекты без какого-либо или полного строкового представления.
ti7

1
Чтобы добавить к точке @ ti7, независимо от технических достоинств ответа, этот пост не VLQ. Если кто-то считает, что этот ответ является неточным, он должен понизить голос и / или прокомментировать, объясняя почему, а не помечать его как VLQ.
EJoshuaS - Восстановить Монику
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.