【问题标题】:Writing unicode strings via sys.stdout in Python在 Python 中通过 sys.stdout 编写 unicode 字符串
【发布时间】:2010-12-01 05:00:51
【问题描述】:

暂时假设不能使用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。在这种情况下,上面的代码会失败。

【问题讨论】:

  • s/my/one's/ 以保持一致性

标签: python unicode macos terminal stdout


【解决方案1】:

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

【讨论】:

  • 我不能使用print 的一个原因是为了避免打印出额外的空间print。看这里sys.stdout的使用:stackoverflow.com/questions/1396820/…
  • 你可以建立完整的线条,然后打印出来。
  • 添加逗号不会打印换行符,但会打印额外的空格。尝试运行: python -c "p​​rint 2,; print 3,"
  • 如果输出到管道,它不可能知道使用什么编码(因为它不知道 less(1) 在管道的另一端)。因此,您的应用程序必须自己确定/决定编码。
  • 在 Python 3 中,您可以使用 print(stuff, sep='', end='') 来避免多余的空格。而且我怀疑那里也不存在编码问题。
【解决方案2】:

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

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:
      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)
      

      【讨论】:

        【解决方案5】:

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

        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 上却不是......无论如何都对我有用 :)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-03-27
          • 1970-01-01
          • 2011-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-23
          • 2017-11-19
          相关资源
          最近更新 更多