UnicodeDecodeError при использовании кода Python 2.7 на Python 3.7 с cPickle - PullRequest
0 голосов
/ 28 марта 2019

Я пытаюсь использовать cPickle для файла .pkl, созданного из "разобранного" файла .csv.Синтаксический анализ выполняется с использованием предварительно созданного набора инструментов python, который недавно был перенесен в python 3 из python 2 (https://github.com/GEMScienceTools/gmpe-smtk)

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

from smtk.parsers.esm_flatfile_parser import ESMFlatfileParser
parser=ESMFlatfileParser.autobuild("Database10","Metadata10","C:/Python37/TestX10","C:/Python37/NorthSea_Inc_SA.csv")
import cPickle
sm_database = cPickle.load(open("C:/Python37/TestX10/metadatafile.pkl","r"))

Возвращает следующую ошибку:

UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 44: character maps to <undefined>

Из того, что я могу собрать, мне нужно указать кодировку моего файла .pkl, чтобы cPickle работал, но я не знаюкакова кодировка файла, полученного в результате анализа файла .csv, поэтому я не могу использовать cPickle для этого.

Я использовал программное обеспечение для возвышенного текста, чтобы найти его "шестнадцатеричным", ноэто не принятый формат кодирования в Python 3.7, не так ли?

Если кто-нибудь знает, как определить требуемый формат кодирования или как сделать шестнадцатеричное кодирование пригодным для использования в Python 3.7, их помощь будет очень признательна.

PS используемые модули, такие как "ESMFlatfileparser", являются частью предварительно созданного набора инструментов. Учитывая это, есть ли шанс, что мне может понадобиться каким-то образом изменить кодировку в этоммодуль тоже?

1 Ответ

1 голос
/ 28 марта 2019

Код открывает файл в режиме text ('r'), но это должен быть режим binary ('rb').

Из документации для pickle.load (выделено мое):

[] Файл может быть файлом на диске , открытым для двоичного чтения , объектом io.BytesIO или любым другим пользовательским объектом, который соответствует этому интерфейсу.

Поскольку файл открывается в двоичном режиме, нет необходимости указывать аргумент кодирования для open. Может быть необходимо предоставить аргумент кодирования для pickle.load. Из той же документации:

Необязательные ключевые аргументы: fix_imports, кодировка и ошибки, которые используются для управления поддержкой совместимости для потока pickle, сгенерированного Python 2. Если fix_imports имеет значение true, pickle попытается отобразить старые имена Python 2 на новые имена, используемые в Python. 3. Кодирование и ошибки сообщают pickle, как декодировать экземпляры 8-битных строк, выбранные Python 2; по умолчанию они имеют значения «ASCII» и «строгий» соответственно. Кодировка может быть «байтами» для чтения этих 8-битных строковых экземпляров в виде байтовых объектов. Использование encoding = 'latin1' требуется для удаления массивов NumPy и экземпляров datetime, date и time, выбранных Python 2.

Это должно предотвратить UnicodeDecodeError:

sm_database = cPickle.load(open("C:/Python37/TestX10/metadatafile.pkl","rb"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...