Eu estou querendo saber se existe uma maneira de carregar um objeto que foi em conserva em Python 2.4, com Python 3.4.
Eu tenho executado o 2to3 em uma grande quantidade de código legado da empresa para atualizá-lo.
Feito isso, ao executar o arquivo, recebo o seguinte erro:
File "H:\fixers - 3.4\addressfixer - 3.4\trunk\lib\address\address_generic.py"
, line 382, in read_ref_files
d = pickle.load(open(mshelffile, 'rb'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 1: ordinal
not in range(128)
Observando o objeto em conserva na disputa, é um dict
em um dict
, contendo chaves e valores do tipo str
.
Então, minha pergunta é: Existe uma maneira de carregar um objeto, originalmente em conserva no python 2.4, com o python 3.4?
python
python-3.x
pickle
python-2.4
python-2to3
NDevox
fonte
fonte
json
módulo? Talvez você possa escrever um script 2.4 que remova o objeto e o salve como objeto json e, em seguida, escreva um script 3.4 que leia o objeto json e salve-o como um objeto pickle compatível com 3.4. Essa seria uma operação única executada em todos os seus arquivos pickle.Respostas:
Você precisará dizer
pickle.load()
como converter dados de Python bytestring em strings do Python 3 ou podepickle
deixá-los em bytes.O padrão é tentar decodificar todos os dados da cadeia como ASCII, e essa decodificação falhará. Veja a
pickle.load()
documentação :Definir a codificação como
latin1
permite importar os dados diretamente:mas você precisará verificar se nenhuma de suas seqüências de caracteres foi decodificada usando o codec errado; O Latin-1 funciona para qualquer entrada, pois mapeia os valores de bytes de 0 a 255 para os primeiros 256 pontos de código Unicode diretamente.
A alternativa seria carregar os dados
encoding='bytes'
e decodificar todas asbytes
chaves e valores posteriormente.Observe que, até as versões Python anteriores a 3.6.8, 3.7.2 e 3.8.0, a remoção dos
datetime
dados do objeto Python 2 é interrompida, a menos que você o useencoding='bytes'
.fonte
encoding
palavra-chave por completo para Python 2.'encoding': 'latin1'
e enviar ** pickle_options para pickle. Dessa forma, ele deve ser executado nas duas versões.datetime
comentário não foi o principal objetivo desta resposta, mas, para futuros leitores, gostaria de ressaltar que mesmo as versões "fixas" do Python 3 ainda precisamencoding='latin-1'
desatar as datas do Python 2. Se seus dados selecionados do Python 2 incluirem datetime e bytestrings codificados em algo que não seja o Latin-1, você ainda poderá usar melhor,encoding='bytes'
afinal.O uso
encoding='latin1'
causa alguns problemas quando seu objeto contém matrizes numpy.Usar
encoding='bytes'
será melhor.Consulte esta resposta para obter uma explicação completa do uso
encoding='bytes'
fonte
bytes
faz strings em bytes (), então prefiro,latin1
se possível, mas não está claro para mim qual é o problema.numpy.ndarray
(numpy 1.14) em conserva em Python 2.7 usandocPickle.dumps()
, e unpickling em Python 3 compickle.loads(..., encoding='latin1')
funciona bem.