ChatGPT解决这个技术问题 Extra ChatGPT

在 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()

它工作正常。

问题是为什么第一种方法会失败?以及如何插入 bom?

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

不要在 UTF-8 中使用 BOM。请。
@tchrist 嗯?为什么不?
@SalmanPK BOM 在 UTF-8 中不需要,只会增加复杂性(例如,您不能仅连接 BOM 文件并生成有效文本)。见this Q&A;不要错过Q下的大评论

Z
Zanon

我认为问题在于 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 的 suggestion 使用“utf-8-sig”作为编码比自己明确编写 BOM 更好,但我将把这个答案留在这里,因为它解释了之前出了什么问题。


警告:open和open是不一样的。如果您执行“从编解码器导入打开”,它将与您只需键入“打开”不同。
您也可以改用 codecs.open('test.txt', 'w', 'utf-8-sig')
我收到“TypeError:需要一个整数(类型为 str)”。我不明白我们在这里做什么。有人可以帮忙吗?我需要将字符串(段落)附加到文本文件中。在写入之前我需要先将其转换为整数吗?
@Mugen:据我所知,我编写的确切代码工作正常。我建议您提出一个新问题,准确显示您拥有的代码以及错误发生的位置。
@Mugen 您需要调用 codecs.open 而不仅仅是 open
E
Eric O Lebigot

阅读以下内容: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 和预期的 BOM。


谢谢。那行得通(Windows 7 x64,Python 2.7.5 x64)。当您以“a”模式(附加)打开文件时,此解决方案效果很好。
这对我不起作用,Windows 上的 Python 3。我不得不使用 open(file_name, 'wb') as bomfile: bomfile.write(codecs.BOM_UTF8) 然后重新打开文件以进行追加。
也许添加 temp.close()
@user2905353:不需要;这由 opencontext management 处理。
K
Kamran Gasimov

使用这个非常简单。不需要任何库。

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

t
tzot

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

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

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

选择另一个 nit,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'
>>> 

R
Ricardo

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

使用 # coding: utf8 而不是更容易记住的 # -*- coding: utf-8 -*-
我真的很想在 Windows 上看到类似的东西
c
celsowm

python 3.4 >= 使用 pathlib

import pathlib
pathlib.Path("text.txt").write_text(text, encoding='utf-8') #or utf-8-sig for BOM

R
RogerZ

如果您使用的是 pandas.to_excel() 等 Pandas I/O 方法,请添加一个编码参数,例如

pd.to_excel("somefile.xlsx", sheet_name="export", encoding='utf-8')

这适用于我相信的大多数国际角色。