Как кодировать при записи в файл?

#python #unicode #encoding

#python #Юникод #кодирование

Вопрос:

Я пытаюсь записать некоторые данные в файл. В некоторых случаях, очевидно, в зависимости от данных, которые я пытаюсь записать, я получаю ошибку UnicodeEncodeError (UnicodeEncodeError: кодек ‘charmap’ не может кодировать символ ‘U0001f622’ в позиции 141: сопоставление символов) Я провел некоторое исследование и выяснил, что я могу кодировать данные, которые я записываю, с помощью функции encode.

Это код, предшествующий его изменению (не поддерживает Unicode):

     scriptDir = os.path.dirname(__file__)
    path = os.path.join(scriptDir, filename)
    with open(path, 'w') as fp:
        for sentence in iobTriplets:
            fp.write("n".join("{} {} {}".format(triplet[0],triplet[1],triplet[2]) for triplet in sentence))
            fp.write("n")
            fp.write("n")
  

Итак, я подумал, что, возможно, я мог бы просто добавить кодировку при такой записи:

 fp.write("n".join("{} {} {}".format(triplet[0],triplet[1],triplet[2]).encode('utf8') for triplet in sentence))
  

Но это не работает, поскольку я получаю следующую ошибку:
Ошибка типа: элемент последовательности 0: ожидаемый экземпляр str, найдены байты

Я также попытался открыть файл в байтовом режиме с добавлением буквы b после буквы w. Однако это не дало никаких результатов.

Кто-нибудь знает, как это исправить? Кстати: я использую Python 3.

Комментарии:

1. Пожалуйста, опубликуйте исходную ошибку. Кроме того, я предполагаю, что это Python 3?

2. режим должен быть encode('utf-8')

3. Вероятно, в вашей системе установлена кодировка по умолчанию, которая подбирается open , может быть, что-то вроде ASCII. Итак, попробуйте использовать open(path, 'w', encoding='utf-8')

4. @C.Nivs либо работает там. На самом деле, если это Python 3, то вы можете просто сделать encode() . Мне любопытно, почему не работает открытие файла в двоичном режиме. Что означает «Я также попытался открыть файл в байтовом режиме с добавлением буквы b за буквой w . Однако это не дало никаких результатов.» точно имеется в виду

5. В любом случае, вам нужно использовать b'n'.join(...) , если вы собираетесь объединять байты. вероятно, это источник вашей ошибки, но тогда вам придется использовать двоичный режим при открытии файла

Ответ №1:

Вы уже открыли файл с автоматическим кодированием. Нет необходимости что-либо кодировать вручную, если вы не записываете в двоичный файл.
Вы можете указать любую поддерживаемую кодировку в open() :

  with open(path, 'w', encoding='utf-16be') as fp:
  

Если файл не открыт как двоичный, вам нужно удалить str.encode() в fp.write() :

 fp.write("n".join("{} {} {}".format(triplet[0],triplet[1],triplet[2]) for triplet in sentence))