Python 以utf-8格式将unicode字符打印到终端
我使用Python 3.9.1和Linux(CentOS 7)。我想在控制台上打印unicode字符。我想用UTF-8做所有的事情。如果我打开python交互控制台并编写:Python 以utf-8格式将unicode字符打印到终端,python,python-3.x,utf-8,Python,Python 3.x,Utf 8,我使用Python 3.9.1和Linux(CentOS 7)。我想在控制台上打印unicode字符。我想用UTF-8做所有的事情。如果我打开python交互控制台并编写: 打印(“├") 一切顺利,它打印出: ├ 现在我把同一行print(“├“”,然后使用UTF-8编码保存文件(linux上的默认设置)。 然后我得到以下错误: UnicodeEncodeError: 'latin-1' codec can't encode character '\u251c' in position 0:
打印(“├")代码>
一切顺利,它打印出:
├代码>
现在我把同一行print(“├“”
,然后使用UTF-8编码保存文件(linux上的默认设置)。
然后我得到以下错误:
UnicodeEncodeError: 'latin-1' codec can't encode character '\u251c' in position 0: ordinal not in range(256)
“拉丁语-1”是从哪里来的
我还需要在第一行强制使用UTF-8(无论如何,这应该是Python3中的默认值)
但这并没有改变任何事情
关于哪些有效,哪些无效的更多信息:
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编码的源文件中)将字符\u251C
分配到s
的第一个位置,即UTF-8编码的字符串
print(s)
失败,因为这里的print将表示s
的字节发送到标准输出,标准输出需要latin-1
编码。实际上,类似s.encode('latin-1')
的操作失败,因为字符串中的第一个字符无法正确编码
如果您实际运行该语句(s.encode('latin-1')
),您会发现它会导致相同的错误
s2=s.encode('utf8')
工作得很好,它告诉Python将s
的内容显式编码为一个字节序列。s2
现在使用UTF-8编码保存s
的字节编码。(也许'b'是一个更好的变量名,它毕竟不是字符串)
打印(s2)
确实可以打印b'\xe2\x94\x9c'
,因为它只是打印字节序列的Python表示。它不是字符串,所以可以打印值的表示。应该是,它是可以用来定义s2
的文本,即s2=b'\xe2\x94\x9c'
不会改变任何东西
print(s2.decode('latin-1'))
打印正确的东西有点神秘。s2
是U+251C字符的正确UTF-8字节序列()
显然,您的Python获取了s2.decode('latin-1')
的结果,再次将其编码为latin-1
字节序列,然后将其写入输出流,并在输出流中正确呈现
由于Python会对之前尝试打印UTF-8编码字符串的打印语句执行相同的操作,因此它解释了为什么这些语句不能正确显示(或者根本不能显示)
解决方案是显式地告诉Python将标准输出的编码覆盖为UTF-8,这样就可以打印UTF-8字符串,而不用Python尝试将其编码为latin-1
编码字节序列(这将失败)
如本文所述,您可以通过设置SET PYTHONENCODING=UTF-8
来实现这一点。相反,如果您想在交互环境中复制问题,您可能可以通过pythonlegacycynowsstdio
获得该行为
何时何地设置这取决于您的系统环境。其他应用程序依赖于旧的脚本或Python的其他版本不执行此操作吗?如果没有,可以考虑设置全局系统环境变量。或者,您可以在执行脚本之前,即在运行它的批处理文件中设置它。
LANG
环境变量被设置为en_US
,而它应该是en_US.UTF-8
另一种解决问题的方法是将PYTHONENCODING
设置为UTF-8
(对我来说它是空的)
我仍然不完全理解为什么Python只对非交互式脚本感到困惑
更多详细信息:我假设您使用的是Windows?当您运行脚本时,它似乎正在打印到使用latin-1
编码的环境中?即,脚本运行的控制台窗口没有使用UTF-8编码?我不太明白,print(s2.decode('latin-1'))
永远不要打印正确的内容,因为s2是utf-8编码的。请检查环境变量的值。LANG
环境变量设置为什么?他们非常清楚这是Linux环境,所以我认为PYTHONLEGACYWINDOWSSTDIO
不会有任何区别。请尝试import sys;print(sys.stdin.encoding,sys.stdout.encoding)
使用原始的LANG
设置,在交互提示和脚本中查看Python在每个场景中使用的默认编码。您还可以设置PYTHONUTF8=1
以启用UTF-8模式。
s = "├"
#print(s) # FAIL
s2 = s.encode('utf8')
print(s2) # prints b'\xe2\x94\x9c'
print(s2.decode('latin-1')) # prints the right thing