Write to UTF-8 file in Python
我真的对
1 2 3 | file = codecs.open("temp","w","utf-8") file.write(codecs.BOM_UTF8) file.close() |
它给了我错误
UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position
0: ordinal not in range(128)
如果我这样做:
1 2 3 | file = open("temp","w") file.write(codecs.BOM_UTF8) file.close() |
它很好用。
问题是为什么第一种方法失败了?如何插入物料清单?
如果第二种方法是正确的方法,那么使用
我认为问题在于
尝试直接为字节顺序标记(即unicode u+feff)编写unicode字符串,以便文件将其编码为utf-8:
1 2 3 4 5 | import codecs file = codecs.open("lol","w","utf-8") file.write(u'\ufeff') file.close() |
(这似乎给出了正确的答案——一个包含字节ef bb bf的文件。)
edit:s.lott建议使用"utf-8-sig"作为编码,这比自己显式地编写BOM要好,但我将把这个答案留在这里,因为它解释了以前发生的问题。
阅读以下内容:http://docs.python.org/library/codecs.html module-encodings.utf_8_sig
这样做
1 2 3 4 | with codecs.open("test_output","w","utf-8-sig") as temp: temp.write("hi mom ") temp.write(u"This has ?") |
生成的文件是带有预期BOM的UTF-8。
@S-LOTT给出了正确的过程,但是在Unicode问题上进行扩展,Python解释器可以提供更多的见解。
jon skeet对于
1 2 3 4 5 6 | >>> import codecs >>> codecs.BOM '\xff\xfe' >>> codecs.BOM_UTF8 '\xef\xbb\xbf' >>> |
选择另一个NIT,
1 2 3 4 | >>> bom= u" {ZERO WIDTH NO-BREAK SPACE}" >>> bom u'\ufeff' |
也可通过
1 2 3 4 | >>> import unicodedata >>> unicodedata.lookup('ZERO WIDTH NO-BREAK SPACE') u'\ufeff' >>> |
我使用file*nix命令将未知字符集文件转换为utf-8文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # -*- 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() |