Мне интересно, есть ли способ загрузить объект, который был обработан в Python 2.4, с помощью Python 3.4.
Я использовал 2to3 для большого количества устаревшего кода компании, чтобы обновить его.
Сделав это, при запуске файла я получаю следующую ошибку:
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)
Глядя на замаринованный объект в состязании, он находится dict
в a dict
, содержащем ключи и значения типа str
.
Итак, мой вопрос: есть ли способ загрузить объект, изначально маринованный в python 2.4, с помощью python 3.4?
json
модуль? Возможно, вы могли бы написать сценарий 2.4, который распаковывает объект и сохраняет его как объект json, а затем написать сценарий 3.4, который считывает объект json и сохраняет его как совместимый с 3.4 объект pickle. Это будет одноразовая операция, которую вы выполняете для всех файлов рассола.Ответы:
Вам нужно будет рассказать,
pickle.load()
как преобразовать данные строки байтов Python в строки Python 3, или вы можетеpickle
оставить их в виде байтов.По умолчанию выполняется попытка декодирования всех строковых данных как ASCII, и это декодирование не удается. См.
pickle.load()
Документацию :Установка кодировки
latin1
позволяет напрямую импортировать данные:но вам нужно убедиться, что ни одна из ваших строк не декодируется с использованием неправильного кодека; Latin-1 работает для любого ввода, поскольку он напрямую сопоставляет байтовые значения 0–255 с первыми 256 кодовыми точками Unicode.
Альтернативой может быть загрузка данных и последующее
encoding='bytes'
декодирование всехbytes
ключей и значений.Обратите внимание, что до версий Python до 3.6.8, 3.7.2 и 3.8.0 распаковка данных
datetime
объекта Python 2 не выполняется, если вы не используетеencoding='bytes'
.источник
encoding
'encoding': 'latin1'
** pickle_options и отправляет его в pickle. Таким образом, он должен работать в обеих версиях.datetime
комментарий не был основной темой этого ответа, но для будущих читателей я хотел бы указать, что даже «фиксированные» версии Python 3 по-прежнему требуютencoding='latin-1'
отмены выбора времени Python 2. Если ваши консервированные данные Python 2 включают в себя как даты, так и строки байтов, закодированные в чем-то отличном от Latin-1, вам все равно может быть лучше использоватьencoding='bytes'
.Использование
encoding='latin1'
вызывает некоторые проблемы, когда ваш объект содержит в себе массивы numpy.Использование
encoding='bytes'
будет лучше.Пожалуйста, посмотрите этот ответ для полного объяснения использования
encoding='bytes'
источник
bytes
превращает строки в bytes (), поэтому я предпочитаю,latin1
если возможно, но мне не ясно, в чем проблема.numpy.ndarray
(numpy 1.14), маринованный в Python 2.7cPickle.dumps()
, и распаковка в Python 3 сpickle.loads(..., encoding='latin1')
отлично работает.