2009-09-24 20 views
16

假设一个人不能使用print(从而享受自动编码检测的好处)。因此,我们留下了sys.stdout。但是,sys.stdoutnot do any sensible encoding是如此愚蠢。通过Python中的sys.stdout编写unicode字符串

现在一个读取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.encodingNone。在这种情况下,上面的代码将失败。

+0

S /我的/为了一致性 – icedwater 2014-07-11 06:14:28

回答

3

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

+1

我不能使用'print'的一个原因是为了避免额外的空间'print'打印。看看使用'这里sys.stdout':http://stackoverflow.com/questions/1396820/apt-like-column-output-python-library/1397382#1397382 – 2009-09-24 19:52:44

+3

你可以建立完整的生产线,然后打印他们。 – 2009-09-24 20:04:01

+0

Bravo!是的,在这种情况下,我可以用'print' – 2009-09-24 20:13:57

10

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

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

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

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

8

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

27
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) 
+0

非常感谢,为我工作。 – Kino 2017-02-14 08:19:15

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 ...为我工作反正:)

相关问题