Python 3,正在使用sys.stdout.buffer.write()好风格?

时间:2009-06-11 22:08:20

标签: unicode cgi python-3.x

在我了解Python 3.0网页脚本中的reading unicode文件之后,现在是时候让我学习使用带有unicode的print()

我搜索了编写unicode,例如this question解释说你不能将unicode字符写入非unicode控制台。但是,就我而言,输出是给Apache的,我相信它能够处理unicode文本。但是,出于某种原因,我的网页脚本stdout位于ascii

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

的事情
open(filename, 'w', encoding='utf8')

但由于我获得了一个开放的流,我使用了

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

一切似乎都有效。这是否违反某些良好行为规则或有任何意外后果?

2 个答案:

答案 0 :(得分:7)

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

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

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

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

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

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

答案 1 :(得分: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()将关闭底层缓冲区。有些模块使用sys.__stdout__,这只是sys.stdout的别名,所以您可能也想设置它[/ p>

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)