在Python中写入UTF-8文件

251 投票
9 回答
480694 浏览
提问于 2025-04-15 11:57

我对 codecs.open function 感到很困惑。当我执行以下代码时:

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)

但是如果我执行:

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

就没问题了。

我的问题是,为什么第一种方法会失败?我该如何插入 BOM(字节顺序标记)?

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

9 个回答

65

这非常简单,只需要这样做。 不需要任何库。

with open('text.txt', 'w', encoding='utf-8') as f:
    f.write(text)
201

请阅读以下内容: 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格式。

313

我觉得问题在于 codecs.BOM_UTF8 是一个字节字符串,而不是Unicode字符串。我怀疑文件处理器在试图猜测你的意思,因为它看到“我应该写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的文件。)

补充一下:S. Lott的建议使用“utf-8-sig”作为编码,比自己手动写BOM要好,但我还是把这个答案留在这里,因为它解释了之前出错的原因。

撰写回答