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