Utilisation de pickle.dump - TypeError: doit être str, pas d'octets

242

J'utilise python3.3 et j'ai une erreur cryptique en essayant de décaper un dictionnaire simple.

Voici le code:

import os
import pickle
from pickle import *
os.chdir('c:/Python26/progfiles/')

def storvars(vdict):      
    f = open('varstor.txt','w')
    pickle.dump(vdict,f,)
    f.close()
    return

mydict = {'name':'john','gender':'male','age':'45'}
storvars(mydict)

et je reçois:

Traceback (most recent call last):
  File "C:/Python26/test18.py", line 31, in <module>
    storvars(mydict)
  File "C:/Python26/test18.py", line 14, in storvars
    pickle.dump(vdict,f,)
TypeError: must be str, not bytes
John Rowland
la source

Réponses:

404

Le fichier de sortie doit être ouvert en mode binaire:

f = open('varstor.txt','w')

doit être:

f = open('varstor.txt','wb')
Jon Clements
la source
22
Après avoir rencontré exactement le même problème, j'ai vu où le besoin de lecture / écriture "binaire" était mentionné dans les documents pour pickle.dump()et pickle.load(). Les deux endroits, cela n'a été mentionné qu'en passant vers le milieu de l'explication de la fonction. Quelqu'un devrait clarifier cela.
Matthew
9
J'ai déposé # 24159 avec le projet Python. Il y a peut-être quelque chose qui peut être fait pour améliorer l'expérience dans cette situation et dans des situations similaires.
Jason R. Coombs
1
Cet article ne mentionne pas l'utilisation du mode wb et il apparaît en haut des résultats de recherche et a été écrit en 2019 : oughtco.com/using-pickle-to-save-objects-2813661
deltaray
22

Juste eu le même problème. En Python 3, les modes binaires 'wb', 'rb' doivent être spécifiés alors qu'en Python 2x, ils ne sont pas nécessaires. Lorsque vous suivez des didacticiels basés sur Python 2x, c'est pourquoi vous êtes ici.

import pickle

class MyUser(object):
    def __init__(self,name):
        self.name = name

user = MyUser('Peter')

print("Before serialization: ")
print(user.name)
print("------------")
serialized = pickle.dumps(user)
filename = 'serialized.native'

with open(filename,'wb') as file_object:
    file_object.write(serialized)

with open(filename,'rb') as file_object:
    raw_data = file_object.read()

deserialized = pickle.loads(raw_data)


print("Loading from serialized file: ")
user2 = deserialized
print(user2.name)
print("------------")
Eh bien Smith
la source