2013-07-26 2 views
5

私は最近pythonで始まりました。私はそこに、キーボード割り込み処理で遊んで、私はこの振る舞いに出くわしたのPythonで、なぜシグナルハンドリングが "try except"の前後で行われるのか、例外に違いがあります

import signal,sys 

def handleInt(sign,no): 
    print "interrupted" 

signal.signal(signal.SIGINT,handleInt) # exception raised is IOError 

try: 
    sys.stdin.read(1) 
except IOError: 
    print "io interrupt" 

が、私はCtrl + Cを押すと、私は、try-除く

import signal,sys 

def handleInt(sign,no): 
    print "interrupted" 

try: 
    sys.stdin.read(1) 
except KeyboardInterrupt: 
    print "keyboard interrupt" 

signal.signal(signal.SIGINT,handleInt) # exception raised is KeyboardInterrupt 

後にシグナル処理を変更した場合ました2つのケースでの例外の違いです。なぜこの動作ですか?

+0

コードをよく理解できるようにこれを正しくインデントしてください。 –

+0

私はこのコードをpython lintでチェックしました。インデントの問題は表示されません。 – karyboy

+1

2番目のスニペットでは、シグナルハンドラはtry-exceptブロックの後にインストールされます。したがって、私はそれが効果がないと思う。 – nymk

答えて

1

ブロッキングコール後に信号を登録してsys.stdin.readに登録しようとすると、実際にそこに着くことはありません。

Ctrl-Cを押すと例外が発生し、KeyboardInterruptが読み込み中に壊れて、tryにキャッチされます。

実際に最初の例でシグナルハンドラを登録すると、少し異なることが起こっています。割り込みはhandleIntコードで処理されています。

4

PythonにはSIGINT用の独自の組み込みハンドラがあります。このハンドラは単にKeyboardInterruptを生成します。あなたの最初のコードでは、内蔵の新しいハンドラとハンドラを置き換えるので、あなたは、この出力を参照してください。例外が発生しなかったので、io interruptedは、印刷されていないことを

$python test_exc.py 
^Cinterrupted 

は注意を。実際にコードを修正する:

import signal,sys 

def handleInt(sign,no): 
    print "interrupted" 

signal.signal(signal.SIGINT, handleInt) # exception raised is IOError 

try: 
    sys.stdin.read(1) 
except IOError: 
    print "io interrupt" 
else: 
    # else is executed only if no exception was raised 
    print "done" 

あなたが得る:

$python test_exc.py 
^Cinterrupted 

done 

注意をCtrl+Cを打つことは、したがってsys.stdin.read(1)への呼び出しは、あなたがまだプログラムを継続させるためにいくつかのキーを押す必要がないブロックをしていること。

import signal,sys 

def handleInt(sign,no): 
    print "interrupted" 
    raise OSError 

signal.signal(signal.SIGINT, handleInt) # exception raised is IOError 

try: 
    sys.stdin.read(1) 
except IOError: 
    print "io interrupt" 
else: 
    # else is executed only if no exception was raised 
    print "done" 

サンプル実行:sys.stdin.read(1)への呼び出しは、それを生成しているかのようシグナルハンドラ内の例外を上げると、それが発生します

$python test_exc.py 
^Cinterrupted 
Traceback (most recent call last): 
    File "test_exc.py", line 10, in <module> 
    sys.stdin.read(1) 
    File "test_exc.py", line 5, in handleInt 
    raise OSError 
OSError 

注:あなたはsignal.default_int_handlerを経由して、デフォルトのシグナルハンドラにアクセスすることができます。

+0

シグナルハンドラは決して登録されていません... – aychedee

+0

私の場合、「io割り込み」が表示され、elseの文は – karyboy

+0

@karyboyではありませんどのOSを使用していて、どのPythonバージョンですか?私はKubuntu 13.04(Linuxカーネル3.8.0)でPython 2.7.4でテストを行った。 – Bakuriu

関連する問題