web-dev-qa-db-fra.com

TypeError: un objet de type octet est requis, pas 'str' lors de l'ouverture du fichier Pickle Python 2 dans Python 3

J'essaie d'ouvrir un fichier pickle dans Python 3 avec un code qui fonctionnait dans Python 2 mais me donne maintenant une erreur. Voici le code:

with open(file, 'r') as f:
    d = pickle.load(f)

TypeError                                 Traceback (most recent call last)
<ipython-input-25-38f711abef06> in <module>()
      1 with open(file, 'r') as f:
----> 2     d = pickle.load(f)

TypeError: a bytes-like object is required, not 'str'

J'ai vu sur autre SO réponses que les gens rencontraient ce problème lorsqu'ils utilisaient open(file ,'rb') et que le passage à open(file ,'r') le corrigeait. Si cela aide, j'ai essayé open(file ,'rb') juste pour expérimenter et j'ai obtenu l'erreur suivante:

UnpicklingError                           Traceback (most recent call last)
<ipython-input-26-b77842748a06> in <module>()
      1 with open(file, 'rb') as f:
----> 2     d = pickle.load(f)

UnpicklingError: invalid load key, '\x0a'.

Lorsque j'ouvre le fichier avec f = open(file, 'r') et que l'on saisit f, je reçois:

<_io.TextIOWrapper name='D:/LargeDataSets/Enron/final_project_dataset.pkl' mode='r' encoding='cp1252'>

Alors j'ai aussi essayé:

with open(file, 'rb') as f:
    d = pickle.load(f, encoding='cp1252')

et j'ai eu la même erreur qu'avec "rb":

UnpicklingError                           Traceback (most recent call last)
<ipython-input-27-959b1b0496d0> in <module>()
      1 with open(file, 'rb') as f:
----> 2     d = pickle.load(f, encoding='cp1252')

UnpicklingError: invalid load key, '\x0a'.
6
jss367

Explication sur le chargement avec encoding = bytes.

Supposons que vous ayez un dictionnaire à mariner dans Python2

data_dict= {'key1': value1, 'key2': value2}
with open('pickledObj.pkl', 'wb') as outfile:
  pickle.dump(data_dict, outfile)

Décompresser en Python3

with open('pickledObj.pkl', 'rb') as f:
        data_dict = pickle.load(f, encoding='bytes')

Remarque: les clés du dictionnaire ne sont plus des chaînes. Ce sont des octets.

data_dict['key1'] #result in KeyError

data_dict[b'key1'] #gives value1

ou utiliser

data_dict['key1'.encode('utf-8')] #gives value1
6
Sreeragh A R

Oui, il y a quelques changements entre les formats de cornichons Python 2 et 3. Si possible, je vous recommande de créer à nouveau les données picklées à l'aide de Python 3.

Si cela n’est pas possible/facile, essayez de jouer avec différents paramètres d’encodage (avez-vous essayé 'utf8'?) Ou lisez les données avec encoding='bytes' comme indiqué ici puis décodez les chaînes de votre code où vous pourrez inspecter l’objet davantage.

1
metakermit