Ответ 1
Кодирование 'utf-8-sig'
будет использовать подпись BOM от вашего имени.
По какой-то причине у Python возникают проблемы с BOM при чтении строк юникода из файла UTF-8. Рассмотрим следующее:
with open('test.py') as f:
for line in f:
print unicode(line, 'utf-8')
Кажется прямым, не так ли?
Это то, что я думал, пока не запустил его из командной строки и не получил:
UnicodeEncodeError: кодек 'charmap' не может кодировать символ u '\ ufeff' в позиции 0: символьные карты на
<undefined>
Краткий обзор Google показал, что спецификация должна быть очищена вручную:
import codecs
with open('test.py') as f:
for line in f:
print unicode(line.replace(codecs.BOM_UTF8, ''), 'utf-8')
Это работает отлично. Однако я изо всех сил стараюсь увидеть в этом заслугу.
Существует ли обоснование вышеописанного поведения?. Напротив, UTF-16 работает без проблем.
Кодирование 'utf-8-sig'
будет использовать подпись BOM от вашего имени.
Вы писали:
UnicodeEncodeError: 'charmap' codec can't encode character u'\ufeff' in position 0: character maps to <undefined>
Когда вы указываете кодировку "utf-8"
в Python, она берет вас на ваше слово. Файлы UTF-8 arent должны содержать в них спецификацию. Они не требуются и не рекомендуются. Endianness не имеет смысла с 8-битными блоками кода.
Спецификации винта вверх, тоже, потому что вы больше не можете просто делать:
$ cat a b c > abc
если эти файлы UTF-8 имеют посторонние (чтение: любые) спецификации в них. Посмотрите теперь, почему спецификации являются настолько глупыми/вредными/вредными в UTF-8? Они действительно нарушают вещи.
Спецификация - это метаданные, а не данные, а спецификация кодирования UTF-8 не учитывает их, как это делают спецификации UTF-16 и UTF-32. Итак, Python взял вас на ваше слово и последовал спецификации. Трудно обвинить его в этом.
Если вы пытаетесь использовать спецификацию в качестве магического номера типа файлов, чтобы указать содержимое файла, вы действительно не должны этого делать. Вы действительно должны использовать прототип более высокого уровня для этих целей метаданных, как и с типом MIME.
Это просто еще одна ошибка хромой Windows, обходной путь для которой заключается в использовании альтернативной кодировки "utf-8-sig"
для передачи на Python.