Загрузка Python 3 от Python 2 - PullRequest
0 голосов
/ 11 мая 2018

У меня есть файл pickle, который был создан (я не знаю, как именно) в Python 2. Он предназначен для загрузки следующими строками Python 2, которые при использовании в Python 3 (неудивительно) не работают:

with open('filename','r') as f:
    foo, bar = pickle.load(f)

Результат:

Кодек 'ascii' не может декодировать байт 0xc2 в позиции 1219: порядковый номер не в диапазоне (128)

Ручная проверка файла показывает, что он имеет кодировку utf-8, поэтому:

with open('filename','r', encoding='utf-8') as f:
    foo, bar = pickle.load(f)

Результат:

TypeError: требуется объект, подобный байту, а не 'str'

С двоичной кодировкой:

with open('filename','rb', encoding='utf-8') as f:
    foo, bar = pickle.load(f)

Результат:

ValueError: двоичный режим не принимает аргумент кодировки

Без двоичной кодировки:

with open('filename','rb') as f:
    foo, bar = pickle.load(f)

Результат:

UnpicklingError: недопустимый ключ загрузки, ''.

Не поврежден ли этот файл выбора?Если нет, как я могу открыть эту вещь в Python 3?(Я просмотрел обширную коллекцию связанных вопросов и пока не нашел ничего, что работает.)

Наконец, обратите внимание, что оригинальный

импортирует cPickle в виде pickle

был заменен на

import _pickle as pickle

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Загрузке солений python2 в python3 (в данном примере версии 3.7.2) можно помочь с помощью параметра fix_imports в функции pickle.load, но в моем случае это также работало без установки этого параметра. в Истину.

Я пытался загрузить scipy.sparse.csr.csr_matrix, содержащийся в рассоле, сгенерированном с помощью Python2.

При проверке формата файла с помощью команды UNIX file он говорит:

>file -bi python2_generated.pckl
application/octet-stream; charset=binary

Я мог бы загрузить рассол в Python3, используя следующий код:

with open("python2_generated.pckl", "rb") as fd:
    bh01 = pickle.load(fd, fix_imports=True, encoding="latin1")

Обратите внимание, что загрузка прошла успешно с и без установки для fix_imports значения True Что касается кодировки "latin1", то документация Python3 (версия 3.7.2) для функции pickle.load гласит: Использование encoding = 'latin1' требуется для удаления массивов NumPy и экземпляров datetime, date и time, выбранных Python 2

Хотя это специально для матриц Scipy (или массивов Numpy), и поскольку Новак не выясняет, что содержится в его файле рассола, Я надеюсь, что это может помочь другим пользователям :)

0 голосов
/ 13 мая 2018

Две ошибки связывали друг с другом.

Первый : к тому времени, как файл .p дошел до меня, он почти наверняка был поврежден при передаче, вероятно, с помощью FTP (илипохоже) в ASCII, а не в двоичном режиме.Мне удалось достать правильно переданную копию, которая позволила мне обнаружить ...

Секунда : что бы файл ни подразумевал внутри, правильная кодировка была "latin1 'не' utf-8 '.

Так что в некотором смысле, да, файл был сломан, и даже после этого я делал это неправильно.Я оставляю это здесь как напоминание тому, у кого в конечном итоге возникнет следующая причудливая проблема pickle / python2 / python3, что может быть несколько ошибок, и они должны быть решены в правильном порядке.

...