在我了解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'))
一切似乎都有效。这是否违反某些良好行为规则或有任何意外后果?
答案 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)