Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load pickle file(comes from python3) in python2

I have a pickle file, with

>>> with open("wikilinks.pickle", "rb") as f:
...     titles, links = pickle.load(f)
... 
>>> len(titles)
13421

I can load it in python3. However, when I try to load it in python2, I get this message: Traceback (most recent call last):

  File "<stdin>", line 2, in <module>
  File "/usr/lib/python2.7/pickle.py", line 1378, in load
    return Unpickler(file).load()
  File "/usr/lib/python2.7/pickle.py", line 858, in load
    dispatch[key](self)
  File "/usr/lib/python2.7/pickle.py", line 886, in load_proto
    raise ValueError, "unsupported pickle protocol: %d" % proto
ValueError: unsupported pickle protocol: 3

So how to load it in python2?

like image 469
epx Avatar asked Apr 12 '15 07:04

epx


People also ask

Does pickle work across Python versions?

Python's pickle is perfectly cross-platform.

How do I load pickled data in Python?

Python Pickle load To retrieve pickled data, the steps are quite simple. You have to use pickle. load() function to do that. The primary argument of pickle load function is the file object that you get by opening the file in read-binary (rb) mode.

Can python3 import python2 module?

Python 2 and Python 3 were never intended to be compatible internally. In fact, the reason Python 3 exists was to be able to make incompatible changes that would not normally be made in a minor version update, e.g. 2.6 to 2.7. This includes byte codes which may not be compatible even across minor versions.

Is pickle a default Python package?

It adds support for very large objects, pickling more kinds of objects, and some data format optimizations. It is the default protocol starting with Python 3.8.


2 Answers

Read in python3 and save it as python2 format

#!/usr/bin/env python3

import pickle

with open("a.pkl", "rb") as f:
    w = pickle.load(f)

pickle.dump(w, open("a_py2.pkl","wb"), protocol=2)

Then you can load a_py2.pkl in python2.

like image 141
Liang Xiao Avatar answered Sep 27 '22 19:09

Liang Xiao


The default pickling protocol used by default in Python 3 is incompatible with the protocol used by Python 2. However, if you can modify the code that produces wikilink.pickle, you can tell it to use one of the earlier protocols (0, 1, or 2) which Python 2 will understand just fine.

Be warned, though, that Python 3 strings will come up as Unicode strings in Python 2, which may be surprising in some use cases.

$ python3
Python 3.4.1 (default, May 19 2014, 17:23:49) 
[GCC 4.9.0 20140507 (prerelease)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> pickle.dumps([1, 2, 'abc'], 2)
b'\x80\x02]q\x00(K\x01K\x02X\x03\x00\x00\x00abcq\x01e.'
>>> 
$ python 
Python 2.7.8 (default, Jul  1 2014, 17:30:21) 
[GCC 4.9.0 20140604 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cPickle
>>> cPickle.loads('\x80\x02]q\x00(K\x01K\x02X\x03\x00\x00\x00abcq\x01e.')
[1, 2, u'abc']
like image 33
user4815162342 Avatar answered Sep 27 '22 19:09

user4815162342