我正在尝试将符号●
写入python中的文本文件。我认为它与编码有关(utf-8)。这是代码:
# -*- coding: utf-8 -*-
outFile = open('./myFile.txt', 'wb')
outFile.write("●")
outFile.close()
而不是黑色"●"
我得到"â—"
。我该如何解决这个问题?
答案 0 :(得分:3)
使用io
程序包打开文件,以便同时使用python2
和python3
,并将编码设置为utf8
,以实现此目的。打印时,写入时,写为unicode字符串。
import io
outFile = io.open('./myFile.txt', 'w', encoding='utf8')
outFile.write(u'●')
outFile.close()
在Python 2.7.8
和Python 3.4.2
答案 1 :(得分:1)
如果您使用的是Python 2,请使用codecs.open
代替open
和unicode
代替str
:
# -*- coding: utf-8 -*-
import codecs
outFile = codecs.open('./myFile.txt', 'wb', 'utf-8')
outFile.write(u"●")
outFile.close()
在Python 3中,将encoding
关键字参数传递给open
:
# -*- coding: utf-8 -*-
outFile = open('./myFile.txt', 'w', encoding='utf-8')
outFile.write("●")
outFile.close()
答案 2 :(得分:0)
>>> ec = u'\u25cf' # unicode("●", "UTF-8")
>>> open("/tmp/file.txt", "w").write(ec.encode('UTF-8'))
答案 3 :(得分:0)
您的程序所做的是以与程序编辑器相同的编码生成输出文件(顶部的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)
请注意,在文件顶部指定正确的coding
非常重要:这必须是您的程序编辑器的编码。
如果您知道输出文件所需的编码,可以直接将其放在open()
中。否则,上面更通用和可移植的out_encoding
表达式应该适用于大多数计算机上的大多数用户(即,无论选择哪种编码,他们都应该能够阅读"●"在结果中文件 - 假设他们的计算机编码可以代表它。)
然后你必须打印一个字符串,而不是字节:
outFile.write(u"●")
(注意前导u
,意思是" unicode字符串")。
为了更深入地了解手头的问题,我以前的一个答案应该非常有用:UnicodeDecodeError when redirecting to file。
答案 4 :(得分:0)
这应该可以解决问题
# -*- coding: utf-8 -*-
outFile = open('./myFile.txt', 'wb')
outFile.write(u"\u25CF".encode('utf-8'))
outFile.close()
查看this
答案 5 :(得分:0)
我很抱歉,但是在没有说明文件编码应该是什么的情况下,将符号写入文本文件是完全没有意义的。
初看起来可能并不明显,但文本文件确实是编码的,并且可能以不同的方式编码。如果您只有字母(大写和小写,但没有重音),数字和简单符号(ASCII码低于128的所有内容),一切都应该没问题,因为ASCII 7位现在是一个标准,实际上是那些字符在主要编码中具有相同的表示。
但是只要你得到真正的符号或重音符号,它们的表示就会从一种编码到另一种编码。例如,符号●具有(Python编码)的UTF-8表示:\xe2\x97\x8f
。更糟糕的是,它无法用latin1(ISO-8859-1)编码表示。
另一个例子是法语 e accent aigu :é
它在UTF8中表示为\xc3\xa9
(注意2个字节),但在Latin1中表示为{{1 (单个字节)
所以我使用UTF8编码和命令在我的Ubuntu框中测试了你的代码
\x89
...正确显示了子弹!
cat myFile.txt
(因为您没有在项目符号后添加任何换行符,紧接着它后面的提示)
总结:
您的代码正确地将子弹以UTF8编码方式写入文件。如果您的系统本身使用其他编码(ISO-8859-1或其变体Windows-1252),则无法进行本机转换,因为此编码中不存在此字符。
但您总是可以在支持不同编码的文本编辑器中看到它,例如所有主要系统上都存在的优秀vim。
上述证据:
在Windows 7计算机上,我打开了一个vim窗口并指示它接受带有sba@sba-ubuntu:~/stackoverflow$ cat myFile.txt
●sba@sba-ubuntu:~/stackoverflow$
的utf8。然后我粘贴了OP的原始代码并将其保存到文件:set encoding='utf8'
。
我打开了一个foo.py
窗口并执行cmd.exe
(使用Python 2.7):它创建了一个包含3个字节(hexa)的文件python foo.py
:myFile.txt
这是子弹的e2 97 8f
的utf8表示(我可以使用vim Tools / Hexa convert确认它。)
我甚至可以在空闲时打开●
并实际看到子弹。甚至myFile.txt
也可以显示子弹!
因此,即使在本机上不接受utf-8的Windows 7计算机上,OP的代码也会正确生成一个文本文件,当使用文本编辑器打开时,接受UTF-8 包含项目符号{ {1}}。
当然,如果我尝试在latin1模式下使用vim打开notepad.exe
,我会得到:●
,在代码页850的cmd窗口上,myFile.txt
显示â—
,以及代码页1252(latin1的变体):â - 。
总之,原始OP代码创建了一个正确的utf8编码文件 - 由读取部分正确解释utf8。