gpt4 book ai didi

python - stderr 的 python 默认编码?

转载 作者:太空狗 更新时间:2023-10-29 21:33:09 27 4
gpt4 key购买 nike

我有一个嘈杂的 python 脚本,我想通过将其 stderr 输出定向到/dev/null(使用 bash BTW)来使其静音。

像这样:

python -u parse.py  1> /tmp/output3.txt 2> /dev/null

但它很快就过早退出了。唔。我看不到回溯,因为它当然会随 stderr 一起消失。如果我不将 stderr 指向某处,它会嘈杂地正常运行。

所以让我们尝试将它重定向到某处的文件而不是/dev/null,并查看它输出的内容:

python -u parse.py  1> /tmp/output3.txt 2> /tmp/foo || tail /tmp/foo

Traceback (most recent call last):
File "parse.py", line 79, in <module>
parseit('pages-articles.xml')
File "parse.py", line 33, in parseit
print >>sys.stderr, "bad page title", page_title
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

因此,正在生成的标准错误包含 utf8,并且出于某种原因,python 在重定向时拒绝打印非 ascii,即使它被定向到/dev/null(当然 python 不知道) .

即使 python 脚本包含 utf8,我如何使它的 stderr 静音?有什么方法可以做到这一点而无需在此脚本中将每个打印都重写到 stderr?

最佳答案

您可以通过将 stderr 绑定(bind)到自定义编写器来使其静音:

#!/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文档:

Look up the codec for the given encoding and return its StreamWriter class or factory function. Raises a LookupError in case the encoding cannot be found.

过于简化的观点:

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)

关于python - stderr 的 python 默认编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/637396/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com