2016-04-09 11 views
4
import signal 
import sys 
import time 

def sigint_handler(signal, frame): 
    print "signal" 
    sys.exit(0) 

signal.signal(signal.SIGINT, sigint_handler) 

while 1: 
    try: 
     print "text" 
     time.sleep(2) 
    except KeyboardInterrupt: 
     print "keybi" 
     exit(0) 
    except: 
     print "except" 
     continue 

Wenn ich drücke Ctrl-C ich sehe „Signal“ und „außer“, und das Programm wird nicht beendet.SIGINT und Ausnahme in Python Handhabung

  1. Warum nicht das Programm zu beenden, während es reicht offenbar sys.exit(0)?

  2. Warum erreicht der Programmablauf nicht den Bereich KeyboardInterrupt?

  3. Was ist die prägnante Art und Weise Ctrl-C Arbeit und behandelt jeden except: Fall separat an verschiedenen Orten ohne Verlassen zu machen?

+2

Mögliche Duplikate von [Wie erfasse ich SIGINT in Python?] (Http://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python) – DeepSpace

+0

Duplikat antwortet nicht 1 , was beantwortet wird unter – Foon

Antwort

6

Das Programm wird nicht beendet, weil sys.exit Werke eine SystemExit Ausnahme zu werfen, und Ihre Decke except es gefangen.

Die except KeyboardInterrupt nicht ausgelöst, weil die SIGINT Handler, der Du überschreibt den Handler Standard SIGINT installiert, und der Standard SIGINT Handler sind verantwortlich für ein KeyboardInterrupt erhöhen, wenn Sie Ctrl-C treffen.

Wie für Ihre dritte Frage ist unklar, was Sie fragen.

1

@ user2357112 beantwortete Ihre ersten zwei Fragen, wie zu Ihrer dritten, können Sie Ihre eigene Ausnahme im Signal-Handler erstellen. In diesem Beispiel erhöhen wir MyError im Falle eines SIGINT.

import signal 
import time 

class MyError(Exception): 
    pass 

def handler(sig, frame): 
    raise MyError('Received signal ' + str(sig) + 
        ' on line ' + str(frame.f_lineno) + 
        ' in ' + frame.f_code.co_filename)  

signal.signal(signal.SIGINT, handler) 

try: 
    while 1: 
     time.sleep(1)  # Hit <CTRL>+C here 
except KeyboardInterrupt: 
    print('Keyboard interrupt caught') 
except MyError as err: 
    print("Hiccup:",err) 
    # do stuff 

print('Clean exit') 

Wenn Sie den Anruf signal.signal() kommentieren Sie dann werden Sie eine KeyboardInterrupt erhalten, wie beschrieben.

+0

Und was ist, wenn ich etwas tun und dann beenden will, unabhängig davon, was "außer" Blöcke gibt? – VladimirLenin

+0

Ah ok, ich werde KeyboardInterrupt nur erneut auslösen. – VladimirLenin

+0

Rufen Sie einfach 'sys.exit()' auf, um zu beenden. Das hat beim letzten Mal nicht geklappt, weil du ein "catch-all" hast außer: '. Wenn Sie einen Exit erzwingen möchten (über den Sie vor dem Ausführen sorgfältig nachdenken sollten), können Sie 'os._exit()' aufrufen, aber das kann merkwürdige Nebeneffekte haben, da der Clean-Up-Code nicht ausgeführt wird. – cdarke