次のようなウィンドウでpython 2.6.6コードを書いています:
try:
dostuff()
except KeyboardInterrupt:
print "Interrupted!"
except:
print "Some other exception?"
finally:
print "cleaning up...."
print "done."
dostuff()
は、入力ストリームから一度に 1 行ずつ読み取り、それに基づいて動作する、永遠にループする関数です。ctrl-cを押したときに停止してクリーンアップできるようにしたい.
代わりに起こっているのは、下のコードexcept KeyboardInterrupt:
がまったく実行されていないということです。出力される唯一のものは「クリーンアップ...」であり、その後、次のようなトレースバックが出力されます。
Traceback (most recent call last):
File "filename.py", line 119, in <module>
print 'cleaning up...'
KeyboardInterrupt
そのため、例外処理コードは実行されておらず、トレースバックは、finally 節で KeyboardInterrupt が発生したと主張していますが、そもそも ctrl-c を押すことがその部分を実行させた原因であるため、これは意味がありません! ジェネリックexcept:
句でさえ実行されていません。
編集:コメントに基づいて、try:
ブロックの内容を sys.stdin.read() に置き換えました。finally:
ブロックの最初の行が実行され、同じトレースバックが出力され、説明どおりに問題が発生します。
編集#2: 読み取り後にほとんど何かを追加すると、ハンドラーが機能します。したがって、これは失敗します:
try:
sys.stdin.read()
except KeyboardInterrupt:
...
しかし、これは機能します:
try:
sys.stdin.read()
print "Done reading."
except KeyboardInterrupt:
...
印刷されたものは次のとおりです。
Done reading. Interrupted!
cleaning up...
done.
それで、なぜか「読了」。前の行で例外が発生したにもかかわらず、行が出力されます。それは実際には問題ではありません。明らかに、「try」ブロック内のどこでも例外を処理できなければなりません。ただし、印刷は正常に機能しません。その後、本来のように改行が印刷されません! 「中断」は同じ行に印刷されています...その前に何らかの理由でスペースがあります...?とにかく、その後、コードは想定どおりに動作します。
これは、ブロックされたシステム コール中に割り込みを処理する際のバグのように思えます。