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

lskq00tm  于 2023-04-19  发布在  Python
关注(0)|答案(5)|浏览(147)

我正在运行一个最近的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忽略了它。至少在我的系统上,即使在设置 envvar 之后,我仍然将ascii作为默认编码。

# 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 Package sys.stdout如下:

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

请参阅this gist以获得处理它的小型实用函数。

0yycz8jy

0yycz8jy1#

似乎不建议这样做。
Fedora建议使用using the system locale as the default,但显然这破坏了其他东西。
以下是mailing-list discussion的一段话:

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
iqxoj9l9

iqxoj9l92#

我是这么做的

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

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

注意bangline中的-S。这告诉Python不要自动导入site模块。site模块设置了默认编码,并删除了该方法,因此不能再次设置。但会荣誉已经设置的内容。

drkbr07n

drkbr07n3#

如何在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。
你的语言环境设置(LANGLC_CTYPE)表示一个utf-8语言环境,因此(理论上)你可以直接打印一个utf-8字节串,它应该在你的终端中正确显示(如果终端设置与语言环境设置一致,它们应该是),但你应该避免它:* 不要在脚本中硬编码环境的字符编码 *;直接打印Unicode,而不是
你的问题中有很多错误的假设。
你不需要设置PYTHONIOENCODING来打印Unicode到终端。utf-8语言环境支持所有Unicode字符,也就是说,它可以按原样工作。
你不需要解决方法sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)。如果某些代码(你无法控制)确实需要打印字节,它可能会中断,并且/或者它可能会在printing Unicode to Windows console (wrong codepage, can't print undecodable characters)时中断。正确的locale设置和/或PYTHONIOENCODING envvar就足够了。此外,如果你需要替换sys.stdout,请使用io.TextIOWrapper()而不是像win-unicode-console package那样的codecs模块。
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

不要调用sys.setdefaultencoding("UTF-8");它可能会悄悄地破坏你的数据和/或破坏不期望它的第三方模块。记住,sys.getdefaultencoding()用于将字节串(str)转换为Python 2中的unicode * 隐式 * 例如,"a" + u"b"。另请参阅the quote in @mesilliac's answer

kh212irz

kh212irz4#

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

PYTHONIOENCODING=utf8 python3 yourprogram.py

或者,如果您的程序是全局安装的模块,请执行以下操作:

PYTHONIOENCODING=utf8 yourprogram

在某些平台上,如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

如果你尝试了这个方法,但没有成功,你需要在sudo shell中输入:

sudo /bin/bash
PYTHONIOENCODING=utf8 yourprogram

相关:
1.如何在Python〈3中将UTF-8编码的文本打印到控制台?

  1. Changing default encoding of Python?
  2. Forcing UTF-8 over cp1252 (Python3)
  3. Permanently set Python path for Anaconda within Cygwin
  4. https://superuser.com/questions/1374339/what-does-the-e-in-sudo-e-do
  5. Why bash -c 'var=5 printf "$var"' does not print 5?
  6. https://unix.stackexchange.com/questions/296838/whats-the-difference-between-eval-and-exec
wgeznvg7

wgeznvg75#

虽然意识到OP问题是针对Linux的:当通过搜索引擎在这里结束时,在Windows 10上,以下修复了该问题:

set PYTHONIOENCODING=utf8
python myscript.py

相关问题