19

假设一个人不能使用print(并因此享受自动编码检测的好处)。所以这给我们留下了sys.stdout. 然而,sys.stdout它是如此愚蠢以至于不做任何明智的编码

现在阅读 Python wiki 页面PrintFails并尝试以下代码:

$ python -c 'import sys, codecs, locale; print str(sys.stdout.encoding); \
  sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout);

然而,这也不起作用(至少在 Mac 上)。太明白为什么:

>>> import locale
>>> locale.getpreferredencoding()
'mac-roman'
>>> sys.stdout.encoding
'UTF-8'

(UTF-8 是终端所理解的)。

因此,将上面的代码更改为:

$ python -c 'import sys, codecs, locale; print str(sys.stdout.encoding); \
  sys.stdout = codecs.getwriter(sys.stdout.encoding)(sys.stdout);

现在 unicode 字符串已正确发送到sys.stdout终端并因此正确打印在终端上(sys.stdout连接到终端)。

这是写入 unicode 字符串的正确方法sys.stdout还是我应该做其他事情?

编辑:有时——比如说,当将输出管道传输到less——sys.stdout.encodingNone。在这种情况下,上面的代码将失败。

4

5 回答 5

34
export PYTHONIOENCODING=utf-8

可以完成这项工作,但不能在 python 本身上设置它......

我们可以做的是验证是否没有设置并告诉用户在调用脚本之前设置它:

if __name__ == '__main__':
    if (sys.stdout.encoding is None):
        print >> sys.stderr, "please set python env PYTHONIOENCODING=UTF-8, example: export PYTHONIOENCODING=UTF-8, when write to stdout."
        exit(1)
于 2011-06-15T17:04:06.067 回答
10

最好的办法是检查您是否直接连接到终端。如果是,请使用终端的编码。否则,使用系统首选编码。

if sys.stdout.isatty():
    default_encoding = sys.stdout.encoding
else:
    default_encoding = locale.getpreferredencoding()

始终允许用户指定她想要的任何编码也非常重要。通常我将其设为命令行选项(如),并使用模块-e ENCODING解析它。optparse

另一个好处是不要sys.stdout用自动编码器覆盖。创建您的编码器并使用它,但不要sys.stdout管它。您可以导入将编码的字节串直接写入sys.stdout.

于 2009-09-25T02:55:36.240 回答
9

有一个可选的环境变量“PYTHONIOENCODING”可以设置为所需的默认编码。这将是一种以与所有 Python 一致的方式获取用户所需编码的方法。它隐藏在 Python 手册

于 2010-10-26T20:50:59.943 回答
7

这就是我在我的应用程序中所做的:

sys.stdout.write(s.encode('utf-8'))

这是从 argv 读取 UTF-8 名称的完全相反的修复:

for file in sys.argv[1:]:
    file = file.decode('utf-8')

这是非常丑陋的(恕我直言),因为它迫使您使用 UTF-8 .. 这是 Linux/Mac 上的规范,但在 Windows 上却不是......无论如何都对我有用:)

于 2012-12-04T12:36:40.087 回答
3

我不清楚你为什么不能打印;但假设是这样,是的,这种方法对我来说是正确的。

于 2009-09-24T19:40:07.830 回答