I had headaches getting some pickled files I created in python 2.7 to actually open in python 3.4. I was getting an error message that looked like this:
UnicodeDecodeError: 'ascii' codec can't decode .....
The pickle contained a dictionary, with string keys. So at first I thought it had something to do with python 3 using utf-8 instead of ascii as the default encoding for strings.
So I tried, the following without any success.
filepath = "/path/to/file.pickle" with open(filepath, mode = "rb") as fileObj: obj = pickle.load(fileObj, encoding="utf-8") return obj
I then tried the following, which allowed me to open up the contents of the pickle file.
filepath = "/path/to/file.pickle" with open(filepath, mode = "rb") as fileObj: obj = pickle.load(fileObj, encoding="latin1") return obj
But then when I saved the modified contents back into the pickle file using:
filepath = "/path/to/file.pickle" with open(filepath, mode="wb") as fileObj: pickle.dump(obj, fileObj, protocol=-1)
I was unable to open the pickle in python 2.7.
It turns out that python 3 has introduced two new protocol versions for creating
pickle files. By default, I had been letting the pickle.dump()
function
use the latest protocol available. The problem is that the latest protocol
is not the same in python 2.7 and 3.x series.
The way to save pickle files in a way that is compatible with both python 2.7
and 3.x series is by setting the protocol
to 2
. This is the highest protocol
version that is shared by both python 2.7 and 3.x.
filepath = "/path/to/file.pickle" with open(filepath, mode="wb") as fileObj: pickle.dump(obj, fileObj, protocol=2)
Here is a summary of the different protocol values, and what versions of python they are compatible with.
Note you can comment without any login by: