Usando pickle.dump - TypeError: debe ser str, no bytes

242

Estoy usando python3.3 y tengo un error críptico cuando intento encurtir un diccionario simple.

Aquí está el código:

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)

y obtengo:

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
fuente

Respuestas:

404

El archivo de salida debe abrirse en modo binario:

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

necesita ser:

f = open('varstor.txt','wb')
Jon Clements
fuente
22
Después de encontrar exactamente el mismo problema, vi dónde se mencionaba la necesidad de lectura / escritura "binaria" en los documentos para pickle.dump()y pickle.load(). En ambos lugares, esto se mencionó solo al pasar cerca del medio de la explicación de la función. Alguien debería aclarar esto.
Mateo
99
Archivé # 24159 con el proyecto Python. Quizás haya algo que se pueda hacer para mejorar la experiencia en esta y otras situaciones similares.
Jason R. Coombs
1
Este artículo no menciona el uso del modo wb y aparece en la parte superior de los resultados de búsqueda y fue escrito en 2019: thoughtco.com/using-pickle-to-save-objects-2813661
deltaray
22

Solo tuve el mismo problema. En Python 3, deben especificarse los modos binarios 'wb', 'rb', mientras que en Python 2x no son necesarios. Cuando sigues tutoriales basados ​​en Python 2x, es por eso que estás aquí.

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("------------")
Bien Smith
fuente