如何在Python <3中将UTF-8编码的文本打印到控制台?
问题内容:
我正在运行最新的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)
请参阅此要点,以获取处理它的小型实用程序功能。
问题答案:
如何在Python <3中将UTF-8编码的文本打印到控制台?
print u"some unicode text \N{EURO SIGN}"
print b"some utf-8 encoded bytestring \xe2\x82\xac".decode('utf-8')
即,如果您有Unicode字符串,则直接打印。如果您有一个字节串,请先将其转换为Unicode。
您的语言环境设置(LANG
,LC_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()
打印到控制台时不使用。如果将stdout重定向到文件/管道,除非PYTHOHIOENCODING
已设置,否则它可用作Python
2的后备:
$ 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()
,用于在Python 2中 隐式
地将字节串(str
)转换为/来回转换,例如 。另请参阅
@mesilliac的答案中的引号。unicode
__"a" + u"b"