您可以通过将 stderr 绑定到自定义编写器来使其静音:
#!/usr/bin/env python
import codecs, sys
class NullWriter:
def write(self, *args, **kwargs):
pass
if len(sys.argv) == 2:
if sys.argv[1] == '1':
sys.stderr = NullWriter()
elif sys.argv[1] == '2':
#NOTE: sys.stderr.encoding is *read-only*
# therefore the whole stderr should be replaced
# encode all output using 'utf8'
sys.stderr = codecs.getwriter('utf8')(sys.stderr)
print >>sys.stderr, u"\u20AC" # euro sign
print "ok"
例子:
$ python silence_stderr.py
Traceback (most recent call last):
File "silence_stderr.py", line 11, in <module>
print >>sys.stderr, u"\u20AC"
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)
静音标准错误:
$ python silence_stderr.py 1
ok
编码标准错误:
$ python silence_stderr.py 2
€
ok
注意:我在 emacs 中有上述输出,因此可以在终端中模拟它:
$ python ... 2>out.txt
$ cat out.txt
注意:在 Windows 控制台内(chcp 65001 切换到 'utf-8' 并使用 truetype 字体 (Lucida Console))我得到了奇怪的结果:
C:\> python silence_stderr.py 2
Traceback (most recent call last):
File "silence_stderr.py", line 14, in <module>
print >>sys.stderr, u"\u20AC" # euro sign
File "C:\pythonxy\python\lib\codecs.py", line 304, in write
self.stream.write(data)
IOError: [Errno 13] Permission denied
如果字体不是 truetype,则不会引发异常,但输出错误。
Perl 适用于 truetype 字体:
C:\> perl -E"say qq(\x{20ac})"
Wide character in print at -e line 1.
€
虽然重定向有效:
C:\>python silence_stderr.py 2 2>tmp.log
ok
C:\>cat tmp.log
€
cat: write error: Permission denied
重新评论
来自codecs.getwriter 文档:
查找给定的编解码器
编码并返回其 StreamWriter
类或工厂函数。提出一个
LookupError 以防编码
找不到。
过于简单的观点:
class UTF8StreamWriter:
def __init__(self, writer):
self.writer = writer
def write(self, s):
self.writer.write(s.encode('utf-8'))
sys.stderr = UTF8StreamWriter(sys.stderr)