繁体   English   中英

以 utf-8 格式将 unicode 字符打印到终端

[英]Print unicode characters to terminal in utf-8

我使用 Python 3.9.1 和 Linux (CentOS 7)。 我想将 unicode 字符打印到控制台。 我想在 UTF-8 中做所有事情。 如果我打开 python 交互式控制台并编写:

print("├")

一切顺利,它打印:

现在我把同样的行print("├")放在一个文件中,然后用 UTF-8 编码(Linux 上的默认值)保存文件。 然后我收到以下错误:

UnicodeEncodeError: 'latin-1' codec can't encode character '\u251c' in position 0: ordinal not in range(256)

“latin-1”从何而来?

我也在第一行强制使用 UTF-8(这应该是 Python3 中的默认值)

# coding: utf8

但它不会改变任何东西。

关于什么有效,什么无效的更多信息:

s = "├"
#print(s) # FAIL
s2 = s.encode('utf8')
print(s2) # prints b'\xe2\x94\x9c'
print(s2.decode('latin-1')) # prints the right thing

这里发生了什么? 我可以在脚本中获得与交互式控制台中相同的行为吗?

s = "├" (在您的 UTF-8 编码源文件中)将字符\├分配给s的第一个位置, s是一个 UTF-8 编码字符串。

print(s)失败,因为这里的 print 将表示s的字节发送到标准输出,该输出需要latin-1编码。 实际上,像s.encode('latin-1')失败,因为字符串中的第一个字符无法正确编码。

如果您从字面上运行该语句( s.encode('latin-1') ),您会发现它会导致相同的错误。

s2 = s.encode('utf8')工作得很好,它告诉 Python 将s的内容显式编码为字节序列。 s2现在持有的字节的编码s ,使用UTF-8编码。 (也许 'b' 会是一个更好的变量名,毕竟它不是一个字符串)

print(s2)确实打印b'\\xe2\\x94\\x9c' ,因为它只是打印字节序列的 Python 表示。 它不是字符串,因此您可以打印出值的表示形式。 应该是,它是您可以用来定义s2的文字,即s2 = b'\\xe2\\x94\\x9c'不会改变任何东西。

print(s2.decode('latin-1'))打印正确的东西有点神秘。 s2是 U+251C 字符的正确 UTF-8 字节序列 ( https://www.fileformat.info/info/unicode/char/251c/index.htm )

显然,您的 Python 获取s2.decode('latin-1')的结果, s2.decode('latin-1')将其编码为latin-1字节序列,然后将其写入输出流,在那里为您正确呈现。

由于 Python 会对之前尝试打印 UTF-8 编码字符串的打印语句执行相同的操作,因此它解释了为什么这些语句不能正确显示(或根本不能显示)。

解决方案是明确告诉 Python 将标准输出的编码覆盖为 UTF-8,这样您就可以打印 UTF-8 字符串,而无需 Python 尝试将其编码为latin-1编码字节序列(这将失败)。

如此处所述https://docs.python.org/3/using/cmdline.html#envvar-PYTHONIOENCODING您可以通过设置SET PYTHONENCODING=UTF-8来做到这一点。 相反,如果您想在交互式环境中复制问题,您可以使用PYTHONLEGACYWINDOWSSTDIO获得该行为。

何时何地进行设置取决于您的系统环境。 其他应用程序是否依赖较旧的脚本或其他版本的 Python 不这样做? 如果没有,可以考虑设置全局系统环境变量。 或者,您可以在执行脚本之前设置它,即在运行它的批处理文件中。

原因是我的LANG环境变量设置为en_US ,而它应该是en_US.UTF-8

解决问题的另一种方法是将PYTHONENCODING设置为UTF-8 (对我来说它是空的)。

我仍然不完全理解为什么 Python 只对非交互式脚本感到困惑......

更多详情:https ://simulrpi.readthedocs.io/en/latest/display_problems.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM