用Python编写UTF-8文件

我真的与codecs.open function混淆。 当我做:

 file = codecs.open("temp", "w", "utf-8") file.write(codecs.BOM_UTF8) file.close() 

它给了我错误

UnicodeDecodeError:'ascii'编解码器无法解码0位的字节0xef:序号不在范围内(128)

如果我做:

 file = open("temp", "w") file.write(codecs.BOM_UTF8) file.close() 

它工作正常。

问题是为什么第一种方法失败? 而且我该如何插入宝盒?

如果第二种方法是正确的做法,使用codecs.open(filename, "w", "utf-8")什么意思?

我相信问题是codecs.BOM_UTF8是一个字节string,而不是一个Unicodestring。 我怀疑文件处理程序试图猜测你真正的意思是基于“我打算把Unicode编写成UTF-8编码的文本,但你给了我一个字节string!

尝试直接为字节顺序标记(即Unicode U + FEFF)编写Unicodestring,以便该文件将其编码为UTF-8:

 import codecs file = codecs.open("lol", "w", "utf-8") file.write(u'\ufeff') file.close() 

(这似乎给出了正确的答案 – 一个字节EF BB BF的文件。)

编辑:S. Lott build议使用“utf-8-sig”作为编码比自己写明BOM要好,但是我会在这里留下这个答案,因为它解释了之前出现的问题。

阅读以下内容: 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 ♭") 

生成的文件是带有预期BOM的UTF-8。

S-Lott给出了正确的程序,但是扩展了Unicode的问题, Python解释器可以提供更多的见解。

乔恩Skeet是正确的(不寻常的)关于codecs模块 – 它包含字节string:

 >>> import codecs >>> codecs.BOM '\xff\xfe' >>> codecs.BOM_UTF8 '\xef\xbb\xbf' >>> 

select另一个nit, BOM具有标准的Unicode名称,可以input:

 >>> bom= u"\N{ZERO WIDTH NO-BREAK SPACE}" >>> bom u'\ufeff' 

它也可以通过unicodedata访问:

 >>> import unicodedata >>> unicodedata.lookup('ZERO WIDTH NO-BREAK SPACE') u'\ufeff' >>> 

我使用文件* 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()