Я действительно запутался с codecs.open function
. Когда я делаю:
file = codecs.open("temp", "w", "utf-8")
file.write(codecs.BOM_UTF8)
file.close()
Это дает мне ошибку
UnicodeDecodeError: кодек «ascii» не может декодировать байт 0xef в позиции 0: порядковый номер не в диапазоне (128)
Если я сделаю:
file = open("temp", "w")
file.write(codecs.BOM_UTF8)
file.close()
Работает нормально.
Вопрос в том, почему первый метод терпит неудачу? И как мне вставить бом?
Если второй метод является правильным способом, какой смысл использовать codecs.open(filename, "w", "utf-8")
?
python
utf-8
byte-order-mark
Джон Цзян
источник
источник
Ответы:
Я считаю, что проблема в том, что
codecs.BOM_UTF8
это строка байтов, а не строка Юникода. Я подозреваю, что обработчик файлов пытается угадать, что вы на самом деле имеете в виду, основываясь на «Я должен писать Unicode как текст в кодировке UTF-8, но вы дали мне строку байтов!»Попробуйте написать строку Unicode для метки порядка байтов (т.е. Unicode U + FEFF) напрямую, чтобы файл просто кодировал ее как UTF-8:
(Это, кажется, дает правильный ответ - файл с байтами EF BB BF.)
РЕДАКТИРОВАТЬ: Предложение С. Лотта об использовании «utf-8-sig» в качестве кодировки лучше, чем явное написание собственной спецификации, но я оставлю этот ответ здесь, поскольку он объясняет, что происходило раньше.
источник
codecs.open
а не простоopen
Прочитайте следующее: http://docs.python.org/library/codecs.html#module-encodings.utf_8_sig
Сделай это
В результате получается файл UTF-8 с ожидаемой спецификацией.
источник
temp.close()
?open
.@ S-Lott дает правильную процедуру, но, углубляясь в проблемы Unicode , интерпретатор Python может предоставить больше информации.
Джон Скит прав (необычен) в отношении
codecs
модуля - он содержит байтовые строки:Выбирая другую гадость, она
BOM
имеет стандартное имя Unicode , и его можно ввести как:Это также доступно через
unicodedata
:источник
Я использую команду file * nix для преобразования неизвестного файла кодировки в файл utf-8
источник
# coding: utf8
вместо# -*- coding: utf-8 -*-
которого гораздо легче запомнить.