代码之家  ›  专栏  ›  技术社区  ›  ilya n.

python 3,使用sys.stdout.buffer.write()的样式好吗?

  •  6
  • ilya n.  · 技术社区  · 15 年前

    在我了解到 reading python 3.0web脚本中的unicode文件,现在是我学习使用的时候了 print() 使用Unicode。

    例如,我搜索了写Unicode this question 说明不能将Unicode字符写入非Unicode控制台。但是,在我的例子中,输出是给Apache的,我确信它能够处理Unicode文本。然而,出于某种原因, stdout 我的网络脚本在 ascii .

    显然,如果我打开一个文件来写自己,我会做

    open(filename, 'w', encoding='utf8')
    

    但既然我有了一个开放的流程,我就开始使用

    sys.stdout.buffer.write(mytext.encode('utf-8'))
    

    一切似乎都正常。这是否违反了良好行为准则或有任何意想不到的后果?

    2 回复  |  直到 8 年前
        1
  •  6
  •   Alex Martelli    15 年前

    我认为你没有违反任何规则,但是

    sys.stdout = codecs.EncodedFile(sys.stdout, 'utf8')
    

    看起来可能更方便/更不笨重。

    编辑:根据评论,这不太正确--@迈尔斯给出了正确的变体(谢谢!):

    sys.stdout = codecs.getwriter('utf8')(sys.stdout.buffer) 
    

    编辑:如果可以排列环境变量 PYTHONIOENCODING 在Apache启动脚本时设置为utf8,这样做会更好,使 sys.stdout 被设定为 utf8 自动的;但是如果这是不可行的或不切实际的 codecs 溶液架。

        2
  •  1
  •   khazhyk    8 年前

    这是一个古老的答案,但我会在这里添加我的版本,因为我在找到解决方案之前第一次来到这里。

    codecs.getwriter的一个问题是,如果您正在运行一个排序脚本,那么输出将被缓冲(而通常python stdout会在每行之后打印)。

    sys.stdout 在控制台中是一个iotextwapper,所以我的解决方案使用它。这也允许您设置line_buffering=true或false。

    例如,要将stdout设置为(而不是错误),反斜杠对所有输出进行编码:

    sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding=sys.stdout.encoding,
                                  errors="backslashreplace", line_buffering=True)
    

    强制特定编码(在本例中为utf8):

    sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding="utf8",
                                  line_buffering=True)
    

    注意,调用sys.stdout.detach()将关闭基础缓冲区。一些模块使用 sys.__stdout__ ,它只是 Sy.StdOUT ,所以您也可以设置

    sys.stdout = sys.__stdout__ = io.TextIOWrapper(sys.stdout.detach(), encoding=sys.stdout.encoding, errors="backslashreplace", line_buffering=True)
    sys.stderr = sys.__stderr__ = io.TextIOWrapper(sys.stderr.detach(), encoding=sys.stdout.encoding, errors="backslashreplace", line_buffering=True)