如何在Python中将符号如●打印到文件中
Posted
技术标签:
【中文标题】如何在Python中将符号如●打印到文件中【英文标题】:How to print symbols like ● to files in Python 【发布时间】:2015-06-26 04:00:38 【问题描述】:我正在尝试将符号 ●
写入 python 中的文本文件。我认为这与编码(utf-8)有关。代码如下:
# -*- coding: utf-8 -*-
outFile = open('./myFile.txt', 'wb')
outFile.write("●")
outFile.close()
我得到的是"â—"
,而不是黑色的"●"
。我该如何解决这个问题?
【问题讨论】:
感谢您的回答!我发现问题是写字板不会显示点,但记事本会。所以实际上它从一开始就奏效了。 Python 2 还是 3? (提示:Py3 更好) 不过,上面的代码仍然存在问题:它基本上只有在 (1) 您的程序编辑器确实使用 UTF-8(可能不是这种情况)和 (2) 使用文本时才有效使用与 您的 编程编辑器相同编码的文件查看器。你可以看看我的解决方案,对于几乎任何机器上应该给出“●”的东西,对于几乎任何用户,无论他们选择的编码是什么。 @JeromeJ:它的python 2 @EOL 不错!很高兴知道! 【参考方案1】:非常抱歉,但是在不说明文件的编码应该是什么的情况下将符号写入文本文件简直是无稽之谈。
乍一看可能并不明显,但文本文件确实是经过编码的,并且可能以不同的方式编码。如果您只有字母(大写和小写,但没有重音)、数字和简单符号(ASCII 码低于 128 的所有内容),一切都应该没问题,因为 ASCII 7 位现在是标准,实际上这些字符在主要编码中具有相同的表示。
但是,一旦您获得真正的符号或重音字符,它们的表示就会因一种编码而异。例如,符号 ● 具有(Python 编码)的 UTF-8 表示:\xe2\x97\x8f
。更糟糕的是,它无法以 latin1 (ISO-8859-1) 编码表示。
另一个例子是法语 e 重音 aigu:é
它在 UTF8 中表示为 \xc3\xa9
(注意 2 个字节),但在 Latin1 中表示为 \x89
(一个单字节)
所以我在我的 Ubuntu 机器中使用 UTF8 编码和命令测试了你的代码
cat myFile.txt
...正确显示了子弹!
sba@sba-ubuntu:~/***$ cat myFile.txt
●sba@sba-ubuntu:~/***$
(由于您没有在项目符号后添加任何换行符,因此提示紧随其后)
总结:
您的代码正确地将项目符号写入 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):它创建了一个包含3 个字节(十六进制)的文件myFile.txt
:e2 97 8f
这是 utf8 表示的bullet ●
(我可以用 vim Tools/Hexa convert 确认)。
我什至可以在空闲状态下打开myFile.txt
并实际看到子弹。甚至notepad.exe
也可以显示子弹!
因此,即使在本机不接受 utf-8 的 Windows 7 计算机上,来自 OP 的代码也会正确生成一个文本文件,当使用接受 UTF-8 的文本编辑器打开时包含项目符号 @ 987654337@.
当然,如果我尝试在 latin1 模式下使用 vim 打开myFile.txt
,我会得到:â—
,在代码页为 850 的 cmd 窗口上,type myFile.txt
显示 ÔùÅ
,代码页为 1252(变体latin1) : ——.
总之,原始 OP 代码创建了一个正确的 utf8 编码文件 - 由读取部分来正确解释 utf8。
【讨论】:
我还修正了您所说的“unicode 表示”,这是不存在的:您实际上是在引用 UTF-8 表示(这不是 Unicode 中的唯一编码)。 最后,代码“以 UTF8 编码正确写入”并不完全正确:只有在使用的程序编辑器确实使用 UTF8 时才会这样做(情况并非总是如此,尤其是在视窗)。关于问题中代码的一般事实是它的输出文件与程序编辑器的编码相同(顶部的coding
无关紧要)。
@EOL :它确实编写了一个可以使用任何可以处理 UTF-8 的编辑器读取的文件。从这个意义上说,它确实以 UTF-8 编码编写了一个文本文件。 vim(或 gvim)在 Windows 中完美运行(它是我最喜欢的通用文本编辑器)。无论如何,感谢您的修复:-)
我一定不同意:只需在不使用 UTF-8 的编辑器/机器中输入原始程序,运行程序,您会看到输出文件不是 UTF-8。即使您无法轻松访问此类编辑器,也可以将顶行更改为 # coding=latin1
(在忽略此行的纯文本编辑器中):您会看到输出不是拉丁语 1: in other换句话说,第一行对于输出的编码并不重要。原始程序中唯一的规范编码是程序编辑器使用的编码。所以,我认为程序一般不会写 UTF-8。
@EOL :第一行 # -*- coding: utf-8 -*-
指示 python 解释器(以及可选的一些文本编辑器,如空闲的),input 脚本文件是 utf8 编码的,对输出。但请参阅我的编辑。【参考方案2】:
您的程序所做的是生成一个输出文件与您的程序编辑器使用相同的编码(顶部的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。
【讨论】:
您的解决方案非常好......不幸的是,子弹在 ISO-8859-1 中没有表示! (或者我找不到它:-() 确实,拉丁文 1 中不存在此项目符号,“•”也不存在。【参考方案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
上测试
【讨论】:
这仅适用于 Python 3,并且仅在所需输出为 UTF-8 时才有效(它不必与程序编辑器使用的编码相同,并且通常会有所不同从机器到机器,尤其是在 Windows 世界和某些国家/地区)。 @EOL,没错。我已经更新了我的答案以弥补我旧答案的不足。谢谢:) 如果您必须在支持 UTF-8 的系统上使用它,那么您不会在编写完全相同文件的原始代码中添加太多内容!【参考方案4】:如果您使用的是 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()
【讨论】:
【参考方案5】:这应该可以解决问题
# -*- coding: utf-8 -*-
outFile = open('./myFile.txt', 'wb')
outFile.write(u"\u25CF".encode('utf-8'))
outFile.close()
看看this
【讨论】:
【参考方案6】:>>> ec = u'\u25cf' # unicode("●", "UTF-8")
>>> open("/tmp/file.txt", "w").write(ec.encode('UTF-8'))
【讨论】:
以上是关于如何在Python中将符号如●打印到文件中的主要内容,如果未能解决你的问题,请参考以下文章