Python中存在已知问题,其中"close failed in file object destructor" when "Broken pipe" happens on stdout - Python tracker Issue 11380;也见于python - Why does my Python3 script balk at piping its output to head or tail (sys module)? - Stack Overflow。在Python 3中禁止打印“Exception ... ignored”消息
我想要做的是在Python 2.7和Python 3+中发生此问题时打印出相同的自定义消息。所以,我准备测试脚本,testprint.py
并运行它(片段显示在bash
做的,Ubuntu 11.04):
$ cat > testprint.py <<"EOF"
import sys
def main():
teststr = "Hello " * 5
sys.stdout.write(teststr + "\n")
if __name__ == "__main__":
main()
EOF
$ python2.7 testprint.py
Hello Hello Hello Hello Hello
$ python2.7 testprint.py | echo
close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
$ python3.2 testprint.py | echo
Exception IOError: (32, 'Broken pipe') in <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> ignored
从上面的链接预期,有两个不同的消息。在Help with a piping error (velocityreviews.com)中,建议使用sys.stdout.flush()
强制Python 2注册IOError而不是该消息;这样,我们有:
$ cat > testprint.py <<"EOF"
import sys
def main():
teststr = "Hello " * 5
sys.stdout.write(teststr + "\n")
sys.stdout.flush()
if __name__ == "__main__":
main()
EOF
$ python2.7 testprint.py | echo
Traceback (most recent call last):
File "testprint.py", line 9, in <module>
main()
File "testprint.py", line 6, in main
sys.stdout.flush()
IOError: [Errno 32] Broken pipe
$ python3.2 testprint.py | echo
Traceback (most recent call last):
File "testprint.py", line 9, in <module>
main()
File "testprint.py", line 6, in main
sys.stdout.flush()
IOError: [Errno 32] Broken pipe
Exception IOError: (32, 'Broken pipe') in <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> ignored
OK,越来越近......现在,“忽略”这些例外(或者对于我来说,用自定义错误消息替换)的方式,是来处理它们:
Ignore exceptions - comp.lang.python
>有没有什么办法让[翻译]忽略例外。
没有。要么处理异常,要么编写不生成异常的代码 。
...以及作为An Introduction to Python - Handling Exceptions笔记,要做到这一点的方法是try/except块。因此,让我们试试:
$ cat > testprint.py <<"EOF"
import sys
def main():
teststr = "Hello " * 5
try:
sys.stdout.write(teststr + "\n")
sys.stdout.flush()
except IOError:
sys.stderr.write("Exc: " + str(sys.exc_info()[0]) + "\n")
if __name__ == "__main__":
main()
EOF
$ python2.7 testprint.py | echo
Exc: <type 'exceptions.IOError'>
$ python3.2 testprint.py | echo
Exc: <class 'IOError'>
Exception IOError: (32, 'Broken pipe') in <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> ignored
好了,尝试/除工程,我希望它的Python 2.7 - 但是,Python的3.2如预期,仍然生成Exception ... ignored
消息两个手柄!有什么问题 - 对于Python 3来说不是“except IOError
”吗?但它一定是 - 否则它不会打印定制的“Exc:...
”消息!
所以 - 这里有什么问题,为什么仍然在Python 3中打印Exception ... ignored
,即使我正在处理异常?更重要的是,我如何处理它,以便 确实不会而不是?
它适用于头部,尾部,更少,更多和独特的我,因此它看起来像是特别与回声的交互中存在实际的错误。 “解析异常”部分实际上是在解释器关闭期间发生的,当它试图再次刷新标准流时。 – ncoghlan 2013-09-23 07:22:08