我想在Python的文本文件中写入符号●
。我认为这与编码(utf-8)有关。以下是代码:
# -*- coding: utf-8 -*-
outFile = open('./myFile.txt', 'wb')
outFile.write("●")
outFile.close()
我得到的不是黑色的"●"
,而是"â—"
。我该怎么解决?
我想在Python的文本文件中写入符号●
。我认为这与编码(utf-8)有关。以下是代码:
# -*- coding: utf-8 -*-
outFile = open('./myFile.txt', 'wb')
outFile.write("●")
outFile.close()
我得到的不是黑色的"●"
,而是"â—"
。我该怎么解决?
使用io
包打开文件,才能使代码在python2
和python3
都能运行,并将编码设置为utf8
。在打印时,以Unicode字符串的形式输出。在写入时,也要写成Unicode字符串。
import io
outFile = io.open('./myFile.txt', 'w', encoding='utf8')
outFile.write(u'●')
outFile.close()
已测试通过Python 2.7.8
和Python 3.4.2
codecs.open
代替open
,并使用unicode
代替str
:# -*- coding: utf-8 -*-
import codecs
outFile = codecs.open('./myFile.txt', 'wb', 'utf-8')
outFile.write(u"●")
outFile.close()
encoding
关键字参数来传递给open
函数:# -*- coding: utf-8 -*-
outFile = open('./myFile.txt', 'w', encoding='utf-8')
outFile.write("●")
outFile.close()
>>> ec = u'\u25cf' # unicode("●", "UTF-8")
>>> open("/tmp/file.txt", "w").write(ec.encode('UTF-8'))
coding
不重要)。因此,如果你用一个使用和你的程序编辑器相同编码方式的程序打开 myFile.txt
,一切看起来都很好。# coding=utf-8 # Put your editor's encoding here
import codecs
import locale
import sys
# Selection of the first non-None, reasonable encoding:
out_encoding = (locale.getlocale()[1]
or locale.getpreferredencoding()
or sys.stdin.encoding or sys.stdout.encoding
# Default:
or "UTF8")
outFile = codecs.open('./myFile.txt', 'w', out_encoding)
outFile.write(u"●")
(请注意前导的u
,表示“Unicode字符串”)。
为了更深入地理解问题,我的一个先前的答案应该非常有帮助:重定向到文件时出现UnicodeDecodeError。
这应该能解决问题
# -*- coding: utf-8 -*-
outFile = open('./myFile.txt', 'wb')
outFile.write(u"\u25CF".encode('utf-8'))
outFile.close()
看一下this
非常抱歉,但是在将符号写入文本文件时没有说明文件的编码方式是毫无意义的。
乍一看可能不明显,但是文本文件确实是编码的,并且可以用不同的方式进行编码。如果您只有字母(大写和小写,但没有重音符号),数字和简单符号(所有ASCII代码低于128的内容),那么一切都应该没问题,因为ASCII 7位现在是标准的,在主要编码中这些字符具有相同的表示。
但是,一旦您获得真正的符号或带重音符号的字符,它们的表示会因编码而异。例如,符号●在UTF-8表示中的Python编码为:\xe2\x97\x8f
。更糟糕的是,它不能用Latin1(ISO-8859-1)编码表示。
另一个例子是法语的e accent aigu: é
,在UTF8中表示为\xc3\xa9
(注意2个字节),但在Latin1中表示为\x89
(仅一个字节)。
所以我在我的Ubuntu系统上使用UTF8编码和命令cat myFile.txt
来测试了你的代码...正确地显示了弹头符号!
sba@sba-ubuntu:~/stackoverflow$ cat myFile.txt
●sba@sba-ubuntu:~/stackoverflow$
总之:
您的代码以UTF8编码正确地将项目符号写入文件。如果您的系统使用本地其他编码(ISO-8859-1或其变体Windows-1252),则无法原生转换它,因为这个字符在这些编码中根本不存在。
但是,您始终可以在支持不同编码的文本编辑器中查看它,例如存在于所有主要系统上的优秀vim。
以上证明:
在Windows 7电脑上,我打开了一个vim窗口,并使用:set encoding='utf8'
指令让它接受utf8编码。然后,我将原始代码从OP粘贴到了一个名为foo.py
的文件中并保存。
我打开了一个cmd.exe
窗口并执行了python foo.py
(使用Python 2.7):它创建了一个名为myFile.txt
的文件,其中包含3个字节(十六进制):e2 97 8f
,这是圆点符号●
的utf8表示形式(我可以通过vim工具/十六进制转换进行确认)。
我甚至可以在idle中打开myFile.txt
并实际看到圆点符号。甚至notepad.exe
也可以显示圆点符号!
因此,即使在不原生接受utf-8的Windows 7电脑上,来自OP的代码仍然可以正确生成一个文本文件,当使用接受UTF-8的文本编辑器打开时,其中包含圆点符号●
。
当然,如果我尝试以Latin1模式用vim打开myFile.txt
,在一个编码为850的cmd窗口上,type myFile.txt
显示ÔùÅ
,而使用1252代码页(Latin1的变体):â—。
总之,原始OP代码创建了一个正确的UTF-8编码文件 - 读取部分需要正确解释UTF-8。
coding
并不重要)。 - Eric O. Lebigot# -*- coding: utf-8 -*-
指示 Python 解释器(以及可选的一些文本编辑器,如 idle)输入脚本文件是 utf8 编码的,并且对输出没有直接影响。但请参见我的编辑。 - Serge Ballesta