I´m trying to save and load objects using pickle
module.
First I declare my objects:
>>> class Fruits:pass
...
>>> banana = Fruits()
>>> banana.color = 'yellow'
>>> banana.value = 30
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 "<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
I 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 "<stdin>", line 1, in <module>
File "C:\Python31\lib\pickle.py", line 1365, in load
encoding=encoding, errors=errors).load()
EOFError
As for your second problem:
After 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:
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:
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 calledklepto
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 aboutklepto
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...
Then we restart…
Klepto
works on python2 and python3.Get the code here: https://github.com/uqfoundation
You're forgetting to read it as binary too.
In your write part you have:
In the read part you have:
So replace it with:
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:
And this (unchanged) to read:
A neater version would be using the
with
statement.For writing:
For reading:
You can use anycache to do the job for you. Assuming you have a function
myfunc
which creates the instance:Anycache calls
myfunc
at the first time and pickles the result to a file incachedir
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:
You didn't open the file in binary mode.
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.
Always open in binary mode, in this case