在Python中通过sys.stdout编写unicode字符串

时间:2009-09-24 19:02:36

标签: python unicode macos terminal stdout

假设一个人不能使用print(从而享受自动编码检测的好处)。所以我们留下了sys.stdout。但是,sys.stdoutnot do any sensible encoding非常愚蠢。

现在,您可以阅读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附加到终端)。

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

编辑:有时 - 比如,将输出汇总到less - sys.stdout.encoding时,None将为{{1}}。在这种情况下,上面的代码将失败。

5 个答案:

答案 0 :(得分:30)

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)

答案 1 :(得分:10)

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

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

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

另一个好处是使用自动编码器覆盖sys.stdout。创建编码器并使用它,但只留下sys.stdout。您可以导入将编码的字节串直接写入sys.stdout的第三方库。

答案 2 :(得分:8)

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

答案 3 :(得分:6)

这就是我在申请中所做的事情:

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上......无论如何都适合我:)

答案 4 :(得分:3)

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