【发布时间】:2014-05-30 00:00:18
【问题描述】:
我想写一个非 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"))
或
getattr(sys.stdout, 'buffer', sys.stdout).write((data["foo"]+u"→").encode("utf8"))
重要的是不要错过→前面的u,否则python2会抛出UnicodeDecodeError。
像这样使用print函数:
print((data["foo"]+u"→").encode("utf8"), file=(getattr(sys.stdout, 'buffer', sys.stdout)))
似乎不起作用,因为 python3 会抱怨 TypeError: 'str' does not support the buffer interface。
我找到了最好的方法还是有更好的选择?我可以让打印功能工作吗?
【问题讨论】:
-
所以
print(data['foo'] + u'→')不起作用? -
@user2357112:不在我的机器上。
-
对于调用
print的最后一个示例,在 Python 3 编码中,字符串返回bytes。由于print需要一个字符串,它调用__str__方法,对于bytes只返回一个repr,即str("→".encode()) == "b'\\xe2\\x86\\x92'"。接下来print将这个无用的repr写入file,但是BufferedWriter需要一个支持buffer接口的对象,比如bytes。 -
@eryksun 谢谢!由于
print()能够打印各种数据类型而无需显式转换为str我不认为它会阻塞bytes。 -
打印必须先获取一个对象作为字符串。这不会让 Python 3
bytes窒息。使用默认编码解码bytes通常是错误的,因为bytes对象不一定是文本。我只是说 repr 字符串对于您的需求是“无用的”。令人窒息的是试图打印到BufferedWriter,例如print('abc', file=sys.stdout.buffer).
标签: python python-3.x encoding stdout