Я пытаюсь сохранять и загружать объекты с помощью pickle
модуля.
Сначала объявляю свои объекты:
>>> class Fruits:pass
...
>>> banana = Fruits()
>>> banana.color = 'yellow'
>>> banana.value = 30
После этого я открываю файл с именем Fruits.obj (ранее я создал новый файл .txt и переименовал его в Fruits.obj):
>>> import pickle
>>> filehandler = open(b"Fruits.obj","wb")
>>> pickle.dump(banana,filehandler)
После этого я закрываю свой сеанс, начинаю новый и помещаю следующий (пытаюсь получить доступ к объекту, который должен быть сохранен):
file = open("Fruits.obj",'r')
object_file = pickle.load(file)
Но у меня есть такое сообщение:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python31\lib\pickle.py", line 1365, in load
encoding=encoding, errors=errors).load()
ValueError: read() from the underlying stream did notreturn bytes
Я не знаю, что делать, потому что не понимаю этого сообщения. Кто-нибудь знает, как я могу загрузить свой объект "банан"? Спасибо!
РЕДАКТИРОВАТЬ: Как некоторые из вас предположили, я поставил:
>>> import pickle
>>> file = open("Fruits.obj",'rb')
Проблем не было, но я поставил следующее:
>>> object_file = pickle.load(file)
И у меня ошибка:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python31\lib\pickle.py", line 1365, in load
encoding=encoding, errors=errors).load()
EOFError
Ответы:
Что касается вашей второй проблемы:
После того, как вы прочитаете содержимое файла, указатель файла будет в конце файла - больше не будет данных для чтения. Вам нужно перемотать файл назад, чтобы он снова читался с начала:
Однако обычно вы хотите использовать диспетчер контекста, чтобы открыть файл и прочитать из него данные. Таким образом, файл будет автоматически закрыт после завершения выполнения блока, что также поможет вам организовать файловые операции в значимые фрагменты.
Наконец, cPickle - это более быстрая реализация модуля pickle на C. Итак:
источник
{"a": 1, "b": 2}
создает словарь с ключами"a"
и"b"
в нем. В онлайн-документации это называется выражением отображения словаря . Это всего лишь один из нескольких способов создания объекта типаdict
, который является одним из нескольких стандартных встроенных типов данных, доступных в Python.pickle
то, что будет импортироватьcpickle
автоматически, если это возможно. docs.python.org/3.1/whatsnew/3.0.html#library-changesДля меня работает следующее:
источник
class Fruits
определение, чтобыpickle.load()
можно было восстановить объект из данных, которые были сохранены в двоичном файле. Лучшая практика для такого рода вещей - поместитьclass Fruits
определение в отдельный файл .py (сделав его настраиваемым модулем), а затемimport
этот модуль или элементы из него, когда это необходимо (т. Е. Оба сеанса). Например, если вы поместите его в файл с именем,MyDataDefs.py
вы можете написатьfrom MyDataDefs import Fruits
. Сообщите мне, если это непонятно, и я соответствующим образом обновлю свой ответ.my_data_defs.py
usingfrom my_data_defs import Fruits
.Вы тоже забываете читать его как двоичный файл.
В вашей части записи у вас есть:
В читаемой части у вас есть:
Поэтому замените его на:
И будет работать :)
Что касается вашей второй ошибки, она, скорее всего, вызвана неправильным закрытием / синхронизацией файла.
Попробуйте написать этот фрагмент кода:
И это (без изменений) читать:
Более аккуратная версия будет использовать это
with
утверждение.Для записи:
Для чтения:
источник
Всегда открывать в двоичном режиме, в этом случае
источник
Вы не открыли файл в двоичном режиме.
Должно сработать.
Для вашей второй ошибки файл, скорее всего, пуст, что означает, что вы случайно очистили его или использовали неправильное имя файла или что-то в этом роде.
(Предполагается, что вы действительно закрыли сеанс. Если нет, то это потому, что вы не закрыли файл между записью и чтением).
Я протестировал ваш код, и он работает.
источник
Кажется, вы хотите сохранять экземпляры классов между сеансами, и использование
pickle
- достойный способ сделать это. Однако есть пакет, называемый,klepto
который абстрагирует сохранение объектов в интерфейсе словаря, поэтому вы можете выбрать объединение объектов и сохранение их в файл (как показано ниже), или объединение объектов и сохранение их в базе данных, или вместо использовать pickle use json или многие другие варианты. Хорошая вещь оklepto
что абстрагирование от общего интерфейса упрощает задачу, так что вам не нужно запоминать низкоуровневые детали того, как сохранить через консервирование в файл или иным образом.Обратите внимание, что он работает для динамически добавляемых атрибутов класса, чего не может сделать pickle ...
Затем перезапускаем…
Klepto
работает на python2 и python3.Получите код здесь: https://github.com/uqfoundation
источник
Вы можете использовать anycache, чтобы сделать эту работу за вас. Предположим, у вас есть функция,
myfunc
которая создает экземпляр:Anycache вызывает
myfunc
в первый раз и сохраняет результат в файл,cachedir
используя уникальный идентификатор (в зависимости от имени функции и аргументов) в качестве имени файла. При любом последовательном прогоне загружается маринованный объект.Если
cachedir
сохраняется между запусками python, маринованный объект берется из предыдущего запуска python.Также учитываются аргументы функции. Реорганизованная реализация работает аналогично:
источник