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

Bru*_*tus 49 python shell encoding ascii 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=
Run Code Online (Sandbox Code Playgroud)

现在我想将UTF-8编码的内容写入控制台.

现在Python使用UTF-8进行FS编码,但坚持使用ASCII作为默认编码:-(

>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>> sys.getfilesystemencoding()
'UTF-8'
Run Code Online (Sandbox Code Playgroud)

我认为最好(干净)的方法是设置PYTHONIOENCODING环境变量.但似乎Python忽略了它.至少在我的系统上ascii,即使在设置envvar之后,我仍然保持默认编码.

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

如果我在脚本开头执行以下操作,它可以工作:

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

但这种做法似乎不洁净.那么,实现这一目标的好方法是什么?

解决方法

而不是更改默认编码 - 这不是一个好主意(请参阅mesilliac的答案) - 我只是sys.stdoutStreamWriter这样的包装:

sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)
Run Code Online (Sandbox Code Playgroud)

请参阅此要点,了解处理它的小型实用程序功能.

mes*_*iac 28

似乎不建议完成此操作.

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


Kei*_*ith 23

我是这样做的:

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

import sys
sys.setdefaultencoding("utf-8")
import site
Run Code Online (Sandbox Code Playgroud)

请注意-S在bangline中.这告诉Python不要自动导入site模块.该site模块设置默认编码并删除方法,因此无法再次设置.但是会尊重已经设定的东西.

  • 这是一个非常糟糕的主意.我已经解决了过去几周中通过从用户代码中删除`sys.setdefaultencoding("utf-8")`来解决的两个问题.恕我直言,这只是掩盖任何潜在的问题 (5认同)

jfs*_*jfs 8

如何在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')
Run Code Online (Sandbox Code Playgroud)

即,如果您有Unicode字符串,则直接打印它.如果您有一个bytestring,那么首先将其转换为Unicode.

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

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

您无需PYTHONIOENCODING使用区域设置进行设置,即可将Unicode打印到终端.utf-8语言环境支持所有Unicode字符,即它按原样工作.

您不需要解决方法sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout).如果某些代码(您不能控制)确实需要打印字节和/或在将Unicode打印到Windows控制台时可能会中断(错误的代码页,无法打印不可解码的字符),则可能会中断 .正确的区域设置和/或PYTHONIOENCODINGenvvar就足够了.此外,如果你需要更换sys.stdout然后使用io.TextIOWrapper()而不是codecswin-unicode-console一样模块.

sys.getdefaultencoding()与您的区域设置无关 PYTHONIOENCODING.您认为设置PYTHONIOENCODING 应该更改的假设sys.getdefaultencoding()是不正确的.你应该检查一下sys.stdout.encoding.

sys.getdefaultencoding()打印到控制台时不使用.如果将stdout重定向到文件/管道,它可以用作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
Run Code Online (Sandbox Code Playgroud)

不要打电话sys.setdefaultencoding("UTF-8"); 它可能会以静默方式破坏您的数据和/或破坏不期望它的第三方模块.记住sys.getdefaultencoding()用于在Python 2中隐式转换bytestrings(str),例如, .另请参阅 @ mesilliac的回答中的引用.unicode"a" + u"b"


use*_*ser 5

如果程序没有在屏幕上显示适当的字符,即无效符号,请使用以下命令行运行程序:

PYTHONIOENCODING=utf8 python3 yourprogram.py
Run Code Online (Sandbox Code Playgroud)

或以下,如果您的程序是全局安装的模块:

PYTHONIOENCODING=utf8 yourprogram
Run Code Online (Sandbox Code Playgroud)

在某些平台上,如 Cygwin(mintty.exe终端)和 Anaconda Python(或Python 3),简单地运行export PYTHONIOENCODING=utf8然后再运行该程序是行不通的,并且您每次都需要始终PYTHONIOENCODING=utf8 yourprogram正确运行该程序。

在 Linux 上,如果是sudo,您可以尝试传递-E参数以将用户变量导出到 sudo 进程:

export PYTHONIOENCODING=utf8
sudo -E python yourprogram.py
Run Code Online (Sandbox Code Playgroud)

如果您尝试此操作但没有奏效,则需要在 sudo shell 上输入:

sudo /bin/bash
PYTHONIOENCODING=utf8 yourprogram
Run Code Online (Sandbox Code Playgroud)

有关的:

  1. 如何在 Python < 3 中将 UTF-8 编码的文本打印到控制台?
  2. 更改 Python 的默认编码?
  3. 强制 UTF-8 超过 cp1252 (Python3)
  4. 在 Cygwin 中为 Anaconda 永久设置 Python 路径
  5. https://superuser.com/questions/1374339/what-does-the-e-in-sudo-e-do
  6. 为什么 bash -c 'var=5 printf "$var"' 不打印 5?
  7. https://unix.stackexchange.com/questions/296838/whats-the-difference-between-eval-and-exec