I´m trying to save and load objects using pickle module.
First I declare my objects:
After that I open a file called 'Fruits.obj'[previously I created a new .txt file and I renamed 'Fruits.obj']:
>>> import pickle >>> filehandler = open[b"Fruits.obj","wb"] >>> pickle.dump[banana,filehandler]After do this I close my session and I began a new one and I put the next [trying to access to the object that it supposed to be saved]:
file = open["Fruits.obj",'r'] object_file = pickle.load[file]But I have this message:
Traceback [most recent call last]: File "", line 1, in File "C:\Python31\lib\pickle.py", line 1365, in load encoding=encoding, errors=errors].load[] ValueError: read[] from the underlying stream did notreturn bytesI don´t know what to do because I don´t understand this message. Does anyone know How I can load my object 'banana'? Thank you!
EDIT: As some of you have sugested I put:
>>> import pickle >>> file = open["Fruits.obj",'rb']There were no problem, but the next I put was:
>>> object_file = pickle.load[file]And I have error:
Traceback [most recent call last]: File "", line 1, in File "C:\Python31\lib\pickle.py", line 1365, in load encoding=encoding, errors=errors].load[] EOFError
martineau
115k25 gold badges160 silver badges282 bronze badges
asked Dec 25, 2010 at 15:17
PeterstonePeterstone
6,63714 gold badges40 silver badges49 bronze badges
2
As for your second problem:
Traceback [most recent call last]: File "", line 1, in File "C:\Python31\lib\pickle.py", line 1365, in load encoding=encoding, errors=errors].load[] EOFErrorAfter you have read the contents of the file, the file pointer will be at the end of the file - there will be no further data to read. You have to rewind the file so that it will be read from the beginning again:
file.seek[0]What you usually want to do though, is to use a context manager to open the file and read data from it. This way, the file will be automatically closed after the block finishes executing, which will also help you organize your file operations into meaningful chunks.
Finally, cPickle is a faster implementation of the pickle module in C. So:
In [1]: import _pickle as cPickle In [2]: d = {"a": 1, "b": 2} In [4]: with open[r"someobject.pickle", "wb"] as output_file: ...: cPickle.dump[d, output_file] ...: # pickle_file will be closed at this point, preventing your from accessing it any further In [5]: with open[r"someobject.pickle", "rb"] as input_file: ...: e = cPickle.load[input_file] ...: In [7]: print e ------> print[e] {'a': 1, 'b': 2}
alper
2,4555 gold badges42 silver badges75 bronze badges
answered Dec 25, 2010 at 15:50
Jim BrissomJim Brissom
30.5k3 gold badges37 silver badges33 bronze badges
4
The following works for me:
class Fruits: pass banana = Fruits[] banana.color = 'yellow' banana.value = 30 import pickle filehandler = open["Fruits.obj","wb"] pickle.dump[banana,filehandler] filehandler.close[] file = open["Fruits.obj",'rb'] object_file = pickle.load[file] file.close[] print[object_file.color, object_file.value, sep=', '] # yellow, 30answered Dec 25, 2010 at 22:05
martineaumartineau
115k25 gold badges160 silver badges282 bronze badges
7
You're forgetting to read it as binary too.
In your write part you have:
open[b"Fruits.obj","wb"] # Note the wb part [Write Binary]In the read part you have:
file = open["Fruits.obj",'r'] # Note the r part, there should be a b tooSo replace it with:
file = open["Fruits.obj",'rb']And it will work :]
As for your second error, it is most likely cause by not closing/syncing the file properly.
Try this bit of code to write:
>>> import pickle >>> filehandler = open[b"Fruits.obj","wb"] >>> pickle.dump[banana,filehandler] >>> filehandler.close[]And this [unchanged] to read:
>>> import pickle >>> file = open["Fruits.obj",'rb'] >>> object_file = pickle.load[file]A neater version would be using the with statement.
For writing:
>>> import pickle >>> with open['Fruits.obj', 'wb'] as fp: >>> pickle.dump[banana, fp]For reading:
>>> import pickle >>> with open['Fruits.obj', 'rb'] as fp: >>> banana = pickle.load[fp]answered Dec 25, 2010 at 15:21
1
Always open in binary mode, in this case
file = open["Fruits.obj",'rb']answered Dec 25, 2010 at 15:20
ismailismail
44.2k8 gold badges84 silver badges95 bronze badges
You can use anycache to do the job for you. Assuming you have a function myfunc which creates the instance:
from anycache import anycache class Fruits:pass @anycache[cachedir='/path/to/your/cache'] def myfunc[] banana = Fruits[] banana.color = 'yellow' banana.value = 30 return bananaAnycache calls myfunc at the first time and pickles the result to a file in cachedir using an unique identifier [depending on the the function name and the arguments] as filename. On any consecutive run, the pickled object is loaded.
If the cachedir is preserved between python runs, the pickled object is taken from the previous python run.
The function arguments are also taken into account. A refactored implementation works likewise:
from anycache import anycache class Fruits:pass @anycache[cachedir='/path/to/your/cache'] def myfunc[color, value] fruit = Fruits[] fruit.color = color fruit.value = value return fruitanswered Nov 19, 2017 at 19:50
c0fec0dec0fec0de
6218 silver badges4 bronze badges
You didn't open the file in binary mode.
open["Fruits.obj",'rb']Should work.
For your second error, the file is most likely empty, which mean you inadvertently emptied it or used the wrong filename or something.
[This is assuming you really did close your session. If not, then it's because you didn't close the file between the write and the read].
I tested your code, and it works.
answered Dec 25, 2010 at 15:21
Lennart RegebroLennart Regebro
161k41 gold badges219 silver badges250 bronze badges
It seems you want to save your class instances across sessions, and using pickle is a decent way to do this. However, there's a package called klepto that abstracts the saving of objects to a dictionary interface, so you can choose to pickle objects and save them to a file [as shown below], or pickle the objects and save them to a database, or instead of use pickle use json, or many other options. The nice thing about klepto is that by abstracting to a common interface, it makes it easy so you don't have to remember the low-level details of how to save via pickling to a file, or otherwise.
Note that It works for dynamically added class attributes, which pickle cannot do...
dude@hilbert>$ python Python 2.7.6 [default, Nov 12 2013, 13:26:39] [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 klepto.archives import file_archive >>> db = file_archive['fruits.txt'] >>> class Fruits: pass ... >>> banana = Fruits[] >>> banana.color = 'yellow' >>> banana.value = 30 >>> >>> db['banana'] = banana >>> db.dump[] >>>Then we restart…
dude@hilbert>$ python Python 2.7.6 [default, Nov 12 2013, 13:26:39] [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 klepto.archives import file_archive >>> db = file_archive['fruits.txt'] >>> db.load[] >>> >>> db['banana'].color 'yellow' >>>Klepto works on python2 and python3.
Get the code here: //github.com/uqfoundation
answered May 21, 2014 at 13:55
Mike McKernsMike McKerns
31.5k8 gold badges111 silver badges137 bronze badges