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

我正在运行一个最新的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环境variables。 但是Python似乎忽略了它。 至less在我的系统上,我保持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的答案) – 我只是用这样的StreamWriter包装sys.stdout

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

看到这个要点处理一个小的实用function。

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

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

即如果你有一个Unicodestring,然后直接打印它。 如果你有一个string,然后将其转换为Unicode第一。

您的语言环境设置( LANGLC_CTYPE )表示utf-8语言环境,因此(理论上)您可以直接打印utf-8string,并且应该在terminal中正确显示(如果terminal设置与语言环境设置一致,应该是),但是你应该避免它: 不要在你的脚本中硬编码你的环境的字符编码 ; 直接打印Unicode

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

您不需要使用您的语言环境设置来设置PYTHONIOENCODING ,以便将Unicode打印到terminal。 UTF-8语言环境支持所有的Unicode字符,即它的工作原理。

您不需要解决方法sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout) 。 如果某些代码(不受控制)确实需要打印字节和/或在将Unicode打印到Windows控制台(错误的代码页,无法打印不可解码的字符)时可能会中断,则可能会中断。 正确的语言环境设置和/或PYTHONIOENCODING envvar就足够了。 此外,如果您需要replacesys.stdout则使用io.TextIOWrapper()而不是像win-unicode-console软件包那样的codecs模块 。

sys.getdefaultencoding()与您的语言环境设置和PYTHONIOENCODING 。 你假设设置PYTHONIOENCODING应该改变sys.getdefaultencoding()是不正确的。 你应该检查sys.stdout.encoding

当您打印到控制台时,不会使用sys.getdefaultencoding() 。 除非设置了PYTHOHIOENCODING否则如果将标准输出redirect到文件/pipe道,它可以用作Python 2的后备function:

 $ 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中的sys.getdefaultencoding() str )转换为unicode ,例如"a" + u"b" 。 另请参阅@ mesilliac的答案中的引用 。

看来完成这不是build议。

Fedorabuild议使用系统区域设置作为默认值 ,但显然这会打破其他的一些东西。

以下是邮件列表讨论的一个引用:

 Python中唯一支持的默认编码是:

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

如果你改变了这些,你就是自己的,奇怪的事情就会发生
开始发生。 默认编码不仅影响
 Python和外部世界之间的翻译,也是
所有8位string和Unicode之间的内部转换。

黑客喜欢什么是在发生在潘戈模块(设置
通过重新加载站点模块,默认编码为“utf-8”
为了得到sys.setdefaultencoding()API)
彻头彻尾的错误,并会导致严重的问题,因为Unicode
对象caching它们的默认编码表示。

请不要启用基于区域的默认编码。

如果你想实现的是获得的编码
标准输出和标准input正确设置pipe道,你应该
而是改变这些(仅)的.encoding属性。

 -  
 Marc-Andre Lemburg
 eGenix.com

这是我如何做到的:

 #!/usr/bin/python2.7 -S import sys sys.setdefaultencoding("utf-8") import site 

注意-S中的bangline。 这就告诉Python不要自动导入site模块。 site模块是设置默认编码和删除的方法,所以它不能再次设置。 但是会尊重已经设定的。