用Python写入UTF-8文件

Joh*_*ang 184 python byte-order-mark utf-8

我真的很困惑codecs.open function.当我做:

file = codecs.open("temp", "w", "utf-8")
file.write(codecs.BOM_UTF8)
file.close()
Run Code Online (Sandbox Code Playgroud)

它给了我错误

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

如果我做:

file = open("temp", "w")
file.write(codecs.BOM_UTF8)
file.close()
Run Code Online (Sandbox Code Playgroud)

它工作正常.

问题是为什么第一种方法失败了?我该如何插入bom?

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

Jon*_*eet 260

我认为问题是codecs.BOM_UTF8字节串,而不是Unicode字符串.我怀疑文件处理程序试图根据"我打算将Unicode编写为UTF-8编码的文本来猜测你的真正意思,但你给了我一个字节字符串!"

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

import codecs

file = codecs.open("lol", "w", "utf-8")
file.write(u'\ufeff')
file.close()
Run Code Online (Sandbox Code Playgroud)

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

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

  • 你也可以使用 codecs.open('test.txt', 'w', 'utf-8-sig') 代替 (2认同)

S.L*_*ott 167

阅读以下内容: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 ?")
Run Code Online (Sandbox Code Playgroud)

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

  • 谢谢。这有效(Windows 7 x64,Python 2.7.5 x64)。当您以“a”(附加)模式打开文件时,此解决方案效果很好。 (2认同)
  • @user2905353:不需要;这是由“open”的[上下文管理](https://docs.python.org/3/reference/datamodel.html#context-managers)处理的。 (2认同)

Kam*_*mov 64

使用这个非常简单。不需要任何图书馆。

with open('text.txt', 'w', encoding='utf-8') as f:
    f.write(text)
Run Code Online (Sandbox Code Playgroud)


gim*_*mel 10

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

Jon Skeet对codecs模块是正确的(不寻常)- 它包含字节字符串:

>>> import codecs
>>> codecs.BOM
'\xff\xfe'
>>> codecs.BOM_UTF8
'\xef\xbb\xbf'
>>> 
Run Code Online (Sandbox Code Playgroud)

选择另一个nit,它BOM有一个标准的Unicode名称,可以输入:

>>> bom= u"\N{ZERO WIDTH NO-BREAK SPACE}"
>>> bom
u'\ufeff'
Run Code Online (Sandbox Code Playgroud)

它也可通过unicodedata以下方式访问:

>>> import unicodedata
>>> unicodedata.lookup('ZERO WIDTH NO-BREAK SPACE')
u'\ufeff'
>>> 
Run Code Online (Sandbox Code Playgroud)


Ric*_*rdo 8

我使用文件*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()
Run Code Online (Sandbox Code Playgroud)