Usando pickle.dump - TypeError: deve ser str, não bytes


242

Estou usando python3.3 e estou tendo um erro enigmático ao tentar selecionar um dicionário simples.

Aqui está o 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)

e eu recebo:

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

Respostas:


404

O arquivo de saída precisa ser aberto no modo binário:

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

precisa ser:

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

22
Depois de encontrar exatamente o mesmo problema, vi onde a necessidade de leitura / gravação "binária" foi mencionada nos documentos para pickle.dump()e pickle.load(). Nos dois lugares, isso foi mencionado apenas de passagem no meio da explicação da função. Alguém deve deixar isso mais claro.
28514 Matthew Matthew

9
Eu arquivei # 24159 com o projeto Python. Talvez haja algo que possa ser feito para melhorar a experiência nesta e em situações semelhantes.
Jason R. Coombs

1
Este artigo não menciona usando o modo WB e aparece no topo dos resultados da pesquisa e foi escrito em 2019: thoughtco.com/using-pickle-to-save-objects-2813661
deltaray

22

Só tive o mesmo problema. No Python 3, os modos binários 'wb', 'rb' devem ser especificados, enquanto no Python 2x, eles não são necessários. Quando você segue tutoriais baseados em Python 2x, é por isso que você está aqui.

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("------------")
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.