Python 2.7:设置I/O编码,'?'

5
尝试在Python 2.7中写入文本文件的一行,以下是代码:
# -*- coding: utf-8 -*-
...
f = open(os.path.join(os.path.dirname(__file__), 'output.txt'), 'w')
f.write('Smith’s BaseBall Cap') // Note the strangely shaped apostrophe

然而,在output.txt中,我却得到了Smith's BaseBall Cap而不是正确的编码。不确定如何纠正这个编码问题?在处理这种问题时有什么技巧吗?

你使用的是哪个Python版本? - BrenBarn
哦,糟糕,是2.7!感谢你的提醒。 - zhuyxn
在OS X 10.6上,这种情况不会发生在其他操作系统上吗?这似乎很奇怪。 - zhuyxn
在另一个系统上,你更有可能得到 â - Josh Lee
2个回答

13
您已经声明您的文件使用UTF-8编码,因此您的字节串文字是以UTF-8格式编码的。弯曲的撇号是U + 2019。在UTF-8中,它被编码为三个字节:\xE2\x80\x99。那三个字节被写入您的输出文件。然后,当您检查输出文件时,它被解释为其他编码方式,所以您看到的是三个错误字符。

Mac OS Roman中,这三个字节显示为‚Äô

您的文件是正确的UTF-8文件,但您的查看方式可能不正确。


没错,但如果他使用常规文件操作来写入字符串,它应该按原样写入,并与输出文件中的UTF-8字节保持一致。 - BrenBarn
1
@BrenBarn:你假设输出文件以UTF-8格式显示,但实际上不是,而是Mac OS Roman格式。 - Ned Batchelder
哦,看来是我用来查看输出的软件(TextEdit)出了问题,如果在命令提示符中使用 cat output.txt,就可以正常工作。 - zhuyxn
2
@zhuyxn,你需要更新或更改你的文本编辑器。如果每个应用程序默认使用UTF-8编码,世界将会更美好。 - Mark Ransom

1

有一些可能性,但首先要检查的是输出文件实际上是否包含您认为它包含的内容。您确定您没有使用错误的编码查看文件吗?有些编辑器有一个选项可以选择您正在查看文件的编码。编辑器需要知道文件的编码,如果它将文件解释为某种其他编码而不是UTF-8,则会显示错误的内容,即使文件的内容是正确的。

当我运行您的代码(在Python 2.6上)时,我在文件中获得了正确的输出。另一个尝试的方法是:使用codecs模块以UTF-8编写打开文件:f = codecs.open("file.txt", "w", "utf-8")。然后声明字符串为unicode字符串,例如u"'Smith’s BaseBall Cap'"`。


2
OS X使用MacRoman作为其默认编码。>>> print u'’'.encode('utf-8').decode('macroman') ‚Äô - Ignacio Vazquez-Abrams
当然可以,但问题在于使用特定程序读取文件时所假定的编码是什么。 - BrenBarn
这是OS X操作系统。因此,程序是TextEdit,并且编码为MacRoman。 - Ignacio Vazquez-Abrams
正确,使用TextEdit打开输出,刚刚意识到如果在命令行中使用cat output.txt,则输出是正确的。 - zhuyxn
出于好奇,codecs.open()通过返回由编解码器定义的包装版本是什么意思(来自文档)?如果我应用这行代码,似乎输出的行会消失。 - zhuyxn
codecs.open 允许您将 Unicode 字符串(而不是 UTF-8 字符串,而是实际的 Unicode 对象)写入文件。 “包装对象” 处理将 Unicode 编码成所选编码(例如 UTF-8)。这就是为什么您必须传递 Unicode 对象,而不是已编码的字节串的原因。 - BrenBarn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接