如何以适用于 python2 和 python3 的方式将 utf8 写入标准输出

2024-01-31

我想写一个非 ASCII 字符,比如说到标准输出。棘手的部分似乎是我想要连接到该字符串的一些数据是从 json 读取的。考虑以下简单的 json 文档:

{"foo":"bar"}

我包含这个是因为如果我只想打印那么似乎只需写一下就足够了:

print("→")

它会在 python2 和 python3 中做正确的事情。

所以我想打印的值foo和我的非 ASCII 字符一起。我发现在 python2 和 python3 中都可以使用的唯一方法是:

getattr(sys.stdout, 'buffer', sys.stdout).write(data["foo"].encode("utf8")+u"→".encode("utf8"))

or

getattr(sys.stdout, 'buffer', sys.stdout).write((data["foo"]+u"→").encode("utf8"))

重要的是不要错过u在...前面因为否则的话UnicodeDecodeError将被 python2 抛出。

使用print像这样的函数:

print((data["foo"]+u"→").encode("utf8"), file=(getattr(sys.stdout, 'buffer', sys.stdout)))

似乎不起作用,因为 python3 会抱怨TypeError: 'str' does not support the buffer interface.

我找到了最好的方法还是有更好的选择?我可以让打印功能起作用吗?


我能想到的最简洁的内容如下,您可以通过一些方便的功能(甚至替换/覆盖打印功能)使其更加简洁:

# -*- coding=utf-8 -*-
import codecs
import os
import sys

# if you include the -*- coding line, you can use this
output = 'bar' + u'→'
# otherwise, use this
output = 'bar' + b'\xe2\x86\x92'.decode('utf-8')

if sys.stdout.encoding == 'UTF-8':
    print(output)
else:
    output += os.linesep
    if sys.version_info[0] >= 3:
        sys.stdout.buffer.write(bytes(output.encode('utf-8')))
    else:
        codecs.getwriter('utf-8')(sys.stdout).write(output)

最好的选择是使用 -*- 编码行,它允许您使用文件中的实际字符。但如果由于某种原因,你不能使用编码线,没有它仍然可以完成。

这(带或不带编码行)适用于使用 python 2.7.7 和 3.4.1 的 Linux (Arch)。 如果终端的编码不是 UTF-8,它也可以工作。 (在 Arch Linux 上,我只是使用不同的 LANG 环境变量来更改编码。)

LANG=zh_CN python test.py

It also sort of适用于 Windows,我在 2.6、2.7、3.3 和 3.4 上尝试过。经过sort of,我的意思是我可以获得'→'仅在 mintty 终端上显示的字符。在 cmd 终端上,该字符将显示为'ΓåÆ'。 (我可能缺少一些简单的东西。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何以适用于 python2 和 python3 的方式将 utf8 写入标准输出 的相关文章

随机推荐