Запись в файл UTF-8 на Python
Я действительно путаю с 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")?
4 ответов:
Я считаю, что проблема в том, что
codecs.BOM_UTF8- это байтовая строка, а не строка Юникода. Я подозреваю, что обработчик файлов пытается угадать, что вы действительно имеете в виду, основываясь на "Я должен писать Unicode как кодированный UTF-8 текст, но вы дали мне байтовую строку!"попробуйте написать строку Unicode для метки порядка байтов (т. е. Unicode U+FEFF) напрямую, так что файл просто кодирует это как UTF-8:
import codecs file = codecs.open("lol", "w", "utf-8") file.write(u'\ufeff') file.close()(это, кажется, дает правильный ответ-файл с байтами EF BB BF.)
EDIT: S. Lott's предложение использования "utf-8-sig" в качестве кодировки лучше, чем явно писать спецификацию самостоятельно, но я оставлю этот ответ здесь, поскольку он объясняет, что было не так раньше.
прочитайте следующее:http://docs.python.org/library/codecs.html#module-encodings.utf_8_sig
этого
with codecs.open("test_output", "w", "utf-8-sig") as temp: temp.write("hi mom\n") temp.write(u"This has ♭")полученный файл будет в кодировке UTF-8 с ожидаемым спецификации.
@S-Lott дает правильную процедуру, но расширяется на Unicode вопросы Python переводчик может предоставить больше информации.
Джон Скит прав (необычно) о
codecsмодуль-содержит байтовые строки:>>> import codecs >>> codecs.BOM '\xff\xfe' >>> codecs.BOM_UTF8 '\xef\xbb\xbf' >>>выбирая другую гниду,
BOMстандартный Unicode имя, и его можно ввести как:>>> bom= u"\N{ZERO WIDTH NO-BREAK SPACE}" >>> bom u'\ufeff'он также доступен через
unicodedata:>>> import unicodedata >>> unicodedata.lookup('ZERO WIDTH NO-BREAK SPACE') u'\ufeff' >>>
Я использую команду file *nix для преобразования неизвестного файла кодировки в файл utf-8
# -*- encoding: utf-8 -*- # converting a unknown formatting file in utf-8 import codecs import commands file_location = "jumper.sub" file_encoding = commands.getoutput('file -b --mime-encoding %s' % file_location) file_stream = codecs.open(file_location, 'r', file_encoding) file_output = codecs.open(file_location+"b", 'w', 'utf-8') for l in file_stream: file_output.write(l) file_stream.close() file_output.close()
Comments