108

私は Python でコマンド ライン ユーティリティを作成していますが、これは運用コードであるため、大量のもの (エラー コード、スタック トレースなど) を画面にダンプすることなく、きれいにシャットダウンできるはずです。これは、キーボード割り込みをキャッチする必要があることを意味します。

次のような try catch ブロックの両方を使用してみました。

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print 'Interrupted'
        sys.exit(0)

そしてシグナル自体をキャッチします(この投稿のように):

import signal
import sys

def sigint_handler(signal, frame):
    print 'Interrupted'
    sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)

どちらの方法も、通常の操作では非常にうまく機能しているようです。ただし、アプリケーションの最後のコードのクリーンアップ中に割り込みが発生した場合、Python は常に画面に何かを出力するようです。割り込みをキャッチすると

^CInterrupted
Exception KeyboardInterrupt in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802852b90>> ignored

一方、信号を処理すると、次のいずれかが得られます

^CInterrupted
Exception SystemExit: 0 in <Finalize object, dead> ignored

また

^CInterrupted
Exception SystemExit: 0 in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802854a90>> ignored

これらのエラーは見苦しいだけでなく、あまり役に立ちません (特にソース コードを持たないエンド ユーザーにとっては)。

このアプリケーションのクリーンアップ コードはかなり大きいため、実際のユーザーがこの問題に遭遇する可能性は十分にあります。この出力をキャッチまたはブロックする方法はありますか、それとも私が対処しなければならないものですか?

4

2 に答える 2

146

このスレッドを確認してください。終了とトレースバックに関する有用な情報がいくつかあります。

プログラムを強制終了することにもっと興味がある場合は、次のようなことを試してください (これにより、クリーンアップ コードの下からも脚が削除されます)。

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print('Interrupted')
        try:
            sys.exit(0)
        except SystemExit:
            os._exit(0)
于 2014-01-15T17:48:43.853 に答える
9

signal.signal(signal.SIGINT, signal.SIG_IGN)クリーンアップ コードを開始する前に呼び出すことで、シャットダウンの開始後に SIGINT を無視できます。

于 2014-01-15T15:38:19.137 に答える