Работа с числами UTF-8 в Python

Предположим, я читаю файл, содержащий 3 числа, разделенные запятыми. Файл сохранен с неизвестной кодировкой, пока имею дело с ANSI и UTF-8. Если файл был в кодировке UTF-8 и в нем была 1 строка со значениями 115,113,12, то:

with open(file) as f:
    a,b,c=map(int,f.readline().split(','))

бросил бы это:

invalid literal for int() with base 10: '\xef\xbb\xbf115'

Первое число всегда искажено этими символами '\xef\xbb\xbf'. Для остальных 2 номеров преобразование работает нормально. Если я вручную заменю '\xef\xbb\xbf' на '', а затем сделаю преобразование int, это сработает.

Есть ли лучший способ сделать это для любого типа закодированного файла?


person Ηλίας    schedule 01.03.2010    source источник


Ответы (2)


import codecs

with codecs.open(file, "r", "utf-8-sig") as f:
    a, b, c= map(int, f.readline().split(","))

Это работает в Python 2.6.4. Вызов codecs.open открывает файл и возвращает данные в формате Unicode, декодируя их из UTF-8 и игнорируя начальную спецификацию.

person tzot    schedule 02.03.2010
comment
Спасибо. Это работает с моими файлами UTF-8, но не работает с Unicode и Unicode с прямым порядком байтов. Есть ли надежный способ открыть любой закодированный файл и получить эти числа, или мне пришлось бы явно указывать кодировку? - person Ηλίας; 02.03.2010
comment
AFAIK вы должны указать кодировку. Очевидно, вы можете написать небольшую функцию, которая выполняет три теста и возвращает правильно декодированный файл. - person tzot; 02.03.2010
comment
Отлично. Я нашел модуль chardet, который делает именно это chardet.feedparser.org. - person Ηλίας; 02.03.2010
comment
Незначительная ошибка в приведенном выше коде: a, b, c= map(int,f.readline().split(,)) - person Ηλίας; 03.03.2010

Вы видите BOM в кодировке UTF-8 или "метку порядка байтов" . Спецификация обычно не используется для файлов UTF-8, поэтому лучший способ справиться с ней может состоять в том, чтобы открыть файл с кодеком UTF-8 и пропустить символ U+FEFF, если он присутствует.

person Greg Hewgill    schedule 01.03.2010