我有以下简单程序:
# -*- coding: utf-8 -*-
GREEK = u'ΑΒΓΔ ΕΖΗΘ ΙΚΛΜ ΝΞΟΠ ΡΣΤΥ ΦΧΨΩ αβγδ εζηθ ικλμ νξοπ ρςτυ φχψω'
print GREEK
在终端上运行此命令会产生,例如:
$ python test.py
ΑΒΓΔ ΕΖΗΘ ΙΚΛΜ ΝΞΟΠ ΡΣΤΥ ΦΧΨΩ αβγδ εζηθ ικλμ νξοπ ρςτυ φχψω
但是将输出传递给另一个程序会导致错误:
$ python test.py | less
Traceback (most recent call last):
File "test.py", line 5, in <module>
print GREEK
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
Traceback (most recent call last):
File "ddd.py", line 5, in <module>
print GREEK
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
less
)。为什么“目标”程序会影响源程序的执行?答案 0 :(得分:6)
基于这个其他相关问题,我已经实现了以下解决方案,它似乎非常强大,并且不需要对我的代码库的所有打印语句进行任何更改:
# -*- coding: utf-8 -*-
import sys
def set_output_encoding(encoding='utf-8'):
import sys
import codecs
'''When piping to the terminal, python knows the encoding needed, and
sets it automatically. But when piping to another program (for example,
| less), python can not check the output encoding. In that case, it
is None. What I am doing here is to catch this situation for both
stdout and stderr and force the encoding'''
current = sys.stdout.encoding
if current is None :
sys.stdout = codecs.getwriter(encoding)(sys.stdout)
current = sys.stderr.encoding
if current is None :
sys.stderr = codecs.getwriter(encoding)(sys.stderr)
GREEK = u'ΑΒΓΔ ΕΖΗΘ ΙΚΛΜ ΝΞΟΠ ΡΣΤΥ ΦΧΨΩ αβγδ εζηθ ικλμ νξοπ ρςτυ φχψω'
set_output_encoding()
print GREEK
print >> sys.stderr, GREEK
测试一下:
python ddd.py # Do not pipe anything
python ddd.py | less # Pipe stdout, let stderr go to the terminal
python ddd.py 2>&1 | less # Pipe both stdout and stderr to less
所有这些都产生了预期的结果:
ΑΒΓΔ ΕΖΗΘ ΙΚΛΜ ΝΞΟΠ ΡΣΤΥ ΦΧΨΩ αβγδ εζηθ ικλμ νξοπ ρςτυ φχψω
ΑΒΓΔ ΕΖΗΘ ΙΚΛΜ ΝΞΟΠ ΡΣΤΥ ΦΧΨΩ αβγδ εζηθ ικλμ νξοπ ρςτυ φχψω
答案 1 :(得分:0)
您的输出程序的编码不支持这些字符。另一种方法是始终对程序中的任何内容进行编码,并在需要时对其进行解码。
# -*- coding: utf-8 -*-
GREEK = u'ΑΒΓΔ ΕΖΗΘ ΙΚΛΜ ΝΞΟΠ ΡΣΤΥ ΦΧΨΩ αβγδ εζηθ ικλμ νξοπ ρςτυ φχψω'
print GREEK.encode('utf-8')
这样可行,但它只显示编码的字符串,而不是原始字符串,因为您的终端应用程序不使用相同的编码。