我想写一个非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
。
我找到了最好的方法还是有更好的选择?我可以使打印功能起作用吗?
答案 0 :(得分:3)
我能想到的最简洁的是以下内容,您可以通过一些便利功能(甚至替换/覆盖打印功能)使其更加简洁:
# -*- 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)
最好的选择是使用 - * - 编码行,它允许您使用文件中的实际字符。但是如果出于某种原因,你不能使用编码行,那么没有它就可以完成。
这个(有和没有编码行)在Linux(Arch)上使用python 2.7.7和3.4.1。 如果终端的编码不是UTF-8,它也可以工作。 (在Arch Linux上,我只是使用不同的LANG环境变量来更改编码。)
LANG=zh_CN python test.py
在Windows上运行,我尝试使用2.6,2.7,3.3和3.4。通过排序,我的意思是我可以让'→'
字符只显示在一个薄薄的终端上。在cmd终端上,该字符将显示为'ΓåÆ'
。 (那里可能有一些简单的东西。)
答案 1 :(得分:1)
如果您不需要打印到sys.stdout.buffer
,则以下内容应该打印到sys.stdout
。我在Python 2.7和3.4中都尝试过它,它似乎运行良好:
# -*- coding=utf-8 -*-
print("bar" + u"→")