如何在终端和文件重定向中打印Unicode

3

我已经阅读了所有有关Unicode、UTF-8、编码/解码等方面的内容,但我仍然感到困难。

我创建了一个简短的示例片段来说明我的问题。

我想打印字符串“Geïrriteerd”,就像它在这里写的一样。如果我使用以下代码将其正确地打印到文件中,并通过重定向到文件运行它,如“Test.py > output”

# coding=utf-8
import codecs
import sys

sys.stdout = codecs.getwriter('UTF-8')(sys.stdout)

print u'Geïrriteerd'

但是如果我不进行重定向操作,上述代码将在终端打印出“Ge├»rriteerd”。如果我删除“codecs.getwriter”行,它就可以正常地打印到终端,但是会在文件中打印出“Ge├»rriteerd”。

如何使它在两种情况下都能正确打印?

我正在使用Windows 10上的Python 2.7。我知道Python 3.x通常更好地处理Unicode,但由于其他依赖关系,我目前无法在我的项目中使用它。

3个回答

2

由于重定向是一个shell操作,因此使用shell控制编码是有意义的。幸运的是,Python提供了一个环境变量来控制编码。给定test.py

#!python2
# coding=utf-8
print u'Geïrriteerd'

要将重定向到特定编码的文件,请使用:

C:\>set PYTHONIOENCODING=utf8
C:\>test >out.txt

如果未定义PYTHONIOENCODING,正常运行脚本将使用终端的编码(在我的情况下是cp437):

C:\>set PYTHONIOENCODING=
C:\>test
Geïrriteerd

1

谢谢,使用这个提示我通过添加一行代码解决了它:
ret = subprocess.check_output('chcp 65001', shell=True) '
- Mytzenka
命令是 chcp.com;如果您使用完整名称和 .com 文件扩展名,则不需要 shell=True。顺便说一下,控制台的 UTF-8 支持存在缺陷。将控制台输入代码页更改为 UTF-8(65001)会在所有 Windows 版本中限制输入为 7 位 ASCII(在 Windows 10 中,非 ASCII 字符将被读取为 '\0')。对于 Python 2 和 Windows 7 及更早版本,将输出代码页设置为 65001 将在将非 ASCII 打印到控制台时产生垃圾输出,甚至在控制台使用 OEM 光栅字体时完全失败。 - Eryk Sun
如果你需要在Windows控制台支持Unicode,最好在Python 2.x和Python 3.0-3.5中使用win_unicode_console - Eryk Sun

1
你需要先对unicode进行"编码",然后才能写入文件或显示。实际上并不需要使用codecs模块。 文档提供了与unicode相关的非常好的示例。
print type(u'Geïrriteerd')
print type(u'Geïrriteerd'.encode('utf-8'))
print u'Geïrriteerd'.encode('utf-8')

with open('test.txt', 'wb') as f:
    f.write(u'Geïrriteerd'.encode('utf-8'))

with open('test.txt', 'r') as f:
    content = f.read()
    print content

#If you want to use codecs still    
import codecs
with codecs.open("test.txt", "w", encoding="utf-8") as f:
    f.write(u'Geïrriteerd')

with open('test.txt', 'r') as f:
    content = f.read()
    print content

1
谢谢。我也尝试在之前添加 .encode('utf-8'),但仍然不能在上面的示例中正常工作。显然问题出在我的终端没有使用 UTF-8。 - Mytzenka

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