9

在我了解了如何在 Python 3.0 Web 脚本中读取unicode 文件之后,现在是我学习使用print()unicode 的时候了。

我搜索了写 unicode,例如这个问题解释了你不能将 unicode 字符写入非 unicode 控制台。但是,就我而言,输出是提供给 Apache 的,我确信它能够处理 unicode 文本。但是,出于某种原因,stdout我的网络脚本位于ascii.

显然,如果我要打开一个文件来写自己,我会做类似的事情

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

但由于我得到了一个开放的流,我求助于使用

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

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

4

2 回答 2

10

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

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

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

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

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

编辑:如果您可以在 Apache 启动脚本时将环境变量PYTHONIOENCODING设置为 utf8,那就更好了,sys.stdout可以utf8自动设置;但如果这是不可行或不切实际的codecs解决方案。

于 2009-06-11T22:23:51.980 回答
1

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

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

sys.stdout在控制台中是一个 IOTextWrapper,所以我的解决方案使用它。这也允许您设置 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() 将关闭底层缓冲区。某些模块 use sys.__stdout__,这只是 的别名sys.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)
于 2016-08-31T04:10:14.913 回答