TypeError: требуется байтоподобный объект, а не 'str' при открытии файла Python 2 Pickle в Python 3

Я пытаюсь открыть файл pickle в Python 3 с помощью кода, который работал в Python 2, но теперь выдает ошибку. Вот код:

with open(file, 'r') as f:
    d = pickle.load(f)

TypeError                                 Traceback (most recent call last)
<ipython-input-25-38f711abef06> in <module>()
      1 with open(file, 'r') as f:
----> 2     d = pickle.load(f)

TypeError: a bytes-like object is required, not 'str'

Я видел на других ответах SO, что у людей была эта проблема при использовании open(file ,'rb') и переключение на open(file ,'r') починил это. Если это поможет, я попытался open(file ,'rb') просто поэкспериментировал и получил следующую ошибку:

UnpicklingError                           Traceback (most recent call last)
<ipython-input-26-b77842748a06> in <module>()
      1 with open(file, 'rb') as f:
----> 2     d = pickle.load(f)

UnpicklingError: invalid load key, '\x0a'.

Когда я открываю файл с f = open(file, 'r') и вход f Я получил:

<_io.TextIOWrapper name='D:/LargeDataSets/Enron/final_project_dataset.pkl' mode='r' encoding='cp1252'>

И я тоже попробовал:

with open(file, 'rb') as f:
    d = pickle.load(f, encoding='cp1252')

и получил ту же ошибку, что и при использовании 'rb':

UnpicklingError                           Traceback (most recent call last)
<ipython-input-27-959b1b0496d0> in <module>()
      1 with open(file, 'rb') as f:
----> 2     d = pickle.load(f, encoding='cp1252')

UnpicklingError: invalid load key, '\x0a'.

3 ответа

Решение

После того, как вы просматриваете необработанный файл в Sublime, похоже, что файл был неправильно обработан. Приведенный выше код отлично работает с другой версией этого файла.

Объяснение для загрузки с кодировкой = байтов.

Предположим, у вас есть словарь, который будет добавлен в Python2

data_dict= {'key1': value1, 'key2': value2}
with open('pickledObj.pkl', 'wb') as outfile:
  pickle.dump(data_dict, outfile)

Разрыхление в Python3

with open('pickledObj.pkl', 'rb') as f:
        data_dict = pickle.load(f, encoding='bytes')

Примечание: ключи словаря больше не являются строками. Это байты.

data_dict['key1'] #result in KeyError

data_dict[b'key1'] #gives value1

или использовать

data_dict['key1'.encode('utf-8')] #gives value1

Да, есть некоторые изменения между форматами Python 2 и 3. Если возможно, я бы рекомендовал снова создать маринованные данные, используя Python 3.

Если это невозможно / просто, попробуйте поиграть с разными настройками кодирования (пробовали ли вы 'utf8'?) или чтение данных с помощью encoding='bytes' как упомянуто здесь, а затем расшифровывает строки в вашем коде, где вы можете проверить объект дальше.

Другие вопросы по тегам