Почему строки Unicode Python требуют специальной обработки для спецификации UTF-8? - PullRequest
14 голосов
/ 01 сентября 2011

По некоторым причинам у Python, похоже, возникают проблемы с BOM при чтении строк Unicode из файла 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 работает без проблем.

Ответы [ 2 ]

28 голосов
/ 01 сентября 2011

Кодировка 'utf-8-sig' будет использовать подпись спецификации от вашего имени.

13 голосов
/ 01 сентября 2011

Вы писали:

 UnicodeEncodeError: 'charmap' codec can't encode character u'\ufeff' in position 0: character maps to <undefined>

Когда вы указываете кодировку "utf-8" в Python, она берет вас за слово.UTF-8 файлы не должны содержать в себе спецификацию.Они не требуются и не рекомендуются.Endianness не имеет смысла с 8-битными единицами кода.

спецификации запутывают, тоже , потому что вы больше не можете просто сделать:

$ cat a b c > abc 

, если эти файлы UTF-8 имеют посторонние (читай: любые) спецификациив них.Теперь вы понимаете, почему спецификации так глупы / плохи / вредны в UTF-8?Они на самом деле ломают вещи.

Спецификация - это метаданные, а не данные, и спецификация кодирования UTF-8 не учитывает их, как это делают спецификации UTF-16 и UTF-32.Итак, Python поверил вам на слово и следовал спецификации.Трудно винить в этом.

Если вы пытаетесь использовать спецификацию в качестве магического номера типа файла для указания содержимого файла, вам действительно не следует этого делать.Вы действительно должны использовать протокол высокого уровня для этих целей метаданных, так же, как вы бы использовали тип MIME.

Это просто еще одна ошибка в Windows, обходной путь которой заключается в использовании альтернативной кодировки "utf-8-sig" для передачи на Python.

...