如何打印UTF-8编码的文本在Python <3控制台?(How to print UTF-8

2019-06-17 14:46发布

我运行一个最近的Linux系统中我所有的语言环境是UTF-8:

LANG=de_DE.UTF-8
LANGUAGE=
LC_CTYPE="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
...
LC_IDENTIFICATION="de_DE.UTF-8"
LC_ALL=

现在我想写UTF-8编码的内容到控制台。

眼下Python使用UTF-8的编码FS坚持,但为ASCII的默认编码:-(

>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>> sys.getfilesystemencoding()
'UTF-8'

我以为最好的(干净)的方式来做到这一点是设置PYTHONIOENCODING环境变量。 但似乎Python的忽略它。 至少在我的系统我不断收到ascii作为默认编码,甚至设置ENVVAR后。

# tried this in ~/.bashrc and ~/.profile (also sourced them)
# and on the commandline before running python
export PYTHONIOENCODING=UTF-8

如果我做的在脚本的开始之后,它的工作原理,但:

>>> import sys
>>> reload(sys)  # to enable `setdefaultencoding` again
<module 'sys' (built-in)>
>>> sys.setdefaultencoding("UTF-8")
>>> sys.getdefaultencoding()
'UTF-8'

但是,这做法似乎不干净 。 那么,什么是做到这一点的好办法?

解决方法

除了更改默认编码的-这是不是一个好主意 (见mesilliac的回答) -我只是包装sys.stdout一个StreamWriter是这样的:

sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)

见这个要点的一个小工具功能,处理它。

Answer 1:

如何打印UTF-8编码的文本在Python <3控制台?

print u"some unicode text \N{EURO SIGN}"
print b"some utf-8 encoded bytestring \xe2\x82\xac".decode('utf-8')

也就是说,如果你有一个Unicode字符串,然后直接打印。 如果你有一个字节串,然后先将其转换为Unicode。

您的区域设置( LANGLC_CTYPE )表示UTF-8语言环境,因此(理论上),你可以打印UTF-8,直接字节字符串,它应该正确地在你的终端上显示(如果终端设置与区域设置和他们一致应该是),但你应该避免: 不要硬编码脚本里面环境的字符编码 ; 打印Unicode的,而不是直接

有你的问题很多错误的假设。

你并不需要设置PYTHONIOENCODING您的区域设置,打印Unicode的终端。 UTF-8语言环境支持所有Unicode字符,即,它的工作原理是是。

你不需要解决方法sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout) 。 它可能会破坏如果某些代码(即你不用管)确实需要打印的字节和/或在它可能会破坏打印Unicode到Windows控制台(错误代码页,无法打印不可解码字符) 。 正确的区域设置和/或PYTHONIOENCODING ENVVAR就足够了。 另外,如果你需要更换sys.stdout ,然后使用io.TextIOWrapper()而不是codecs模块像win-unicode-console包一样。

sys.getdefaultencoding()是完全无关的区域设置和PYTHONIOENCODING 。 你的假设,即设置PYTHONIOENCODING应该改变sys.getdefaultencoding()不正确。 您应该检查sys.stdout.encoding代替。

sys.getdefaultencoding()当您打印到控制台未使用。 它可以被用作关于Python 2的回退如果除非标准输出重定向到文件/管PYTHOHIOENCODING设置:

$ python2 -c'import sys; print(sys.stdout.encoding)'
UTF-8
$ python2 -c'import sys; print(sys.stdout.encoding)' | cat
None
$ PYTHONIOENCODING=utf8 python2 -c'import sys; print(sys.stdout.encoding)' | cat
utf8

不要叫sys.setdefaultencoding("UTF-8") ; 它可能会破坏你的数据默默地和/或打破不要指望它的第三方模块。 记住sys.getdefaultencoding()是用来字节串(转换str )到/从unicode在Python 2 隐含例如, "a" + u"b" 又见, 在@ mesilliac的回答报价 。



Answer 2:

似乎完成不建议这样做。

Fedora的建议使用系统区域设置为默认 ,但显然这打破了其他的事情。

下面是从报价邮件列表的讨论 :

The only supported default encodings in Python are:

 Python 2.x: ASCII
 Python 3.x: UTF-8

If you change these, you are on your own and strange things will
start to happen. The default encoding does not only affect
the translation between Python and the outside world, but also
all internal conversions between 8-bit strings and Unicode.

Hacks like what's happening in the pango module (setting the
default encoding to 'utf-8' by reloading the site module in
order to get the sys.setdefaultencoding() API back) are just
downright wrong and will cause serious problems since Unicode
objects cache their default encoded representation.

Please don't enable the use of a locale based default encoding.

If all you want to achieve is getting the encodings of
stdout and stdin correctly setup for pipes, you should
instead change the .encoding attribute of those (only).

-- 
Marc-Andre Lemburg
eGenix.com


Answer 3:

这就是我要做的事:

#!/usr/bin/python2.7 -S

import sys
sys.setdefaultencoding("utf-8")
import site

注意-S在bangline。 这告诉Python来不会自动导入site模块。 该site模块就是设置默认编码和排除方法,因此它不能被重新设置。 但是,将履行哪些功能已经设置。



文章来源: How to print UTF-8 encoded text to the console in Python < 3?