708 Stimmen

Wie kann ich SIGINT in Python erfassen?

Ich arbeite an einem Python-Skript, das mehrere Prozesse und Datenbankverbindungen startet. Von Zeit zu Zeit möchte ich das Skript mit einer Ctrl + C Signal, und ich möchte etwas aufräumen.

In Perl würde ich dies tun:

$SIG{'INT'} = 'exit_gracefully';

sub exit_gracefully {
    print "Caught ^C \n";
    exit (0);
}

Wie kann ich dies analog in Python tun?

1045voto

Matt J Punkte 41229

Registrieren Sie Ihren Handler mit signal.signal wie diese:

#!/usr/bin/env python
import signal
import sys

def signal_handler(sig, frame):
    print('You pressed Ctrl+C!')
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)
print('Press Ctrl+C')
signal.pause()

Code angepasst von aquí .

Mehr Dokumentation über signal kann gefunden werden aquí .

213voto

rledley Punkte 2169

Sie können sie wie eine Ausnahme (KeyboardInterrupt) behandeln, wie jede andere auch. Erstellen Sie eine neue Datei und führen Sie sie in Ihrer Shell mit dem folgenden Inhalt aus, um zu sehen, was ich meine:

import time, sys

x = 1
while True:
    try:
        print x
        time.sleep(.3)
        x += 1
    except KeyboardInterrupt:
        print "Bye"
        sys.exit()

82voto

Udi Punkte 26826

Und als Kontextmanager:

import signal

class GracefulInterruptHandler(object):

    def __init__(self, sig=signal.SIGINT):
        self.sig = sig

    def __enter__(self):

        self.interrupted = False
        self.released = False

        self.original_handler = signal.getsignal(self.sig)

        def handler(signum, frame):
            self.release()
            self.interrupted = True

        signal.signal(self.sig, handler)

        return self

    def __exit__(self, type, value, tb):
        self.release()

    def release(self):

        if self.released:
            return False

        signal.signal(self.sig, self.original_handler)

        self.released = True

        return True

Zu verwenden:

with GracefulInterruptHandler() as h:
    for i in xrange(1000):
        print "..."
        time.sleep(1)
        if h.interrupted:
            print "interrupted!"
            time.sleep(2)
            break

Verschachtelte Handler:

with GracefulInterruptHandler() as h1:
    while True:
        print "(1)..."
        time.sleep(1)
        with GracefulInterruptHandler() as h2:
            while True:
                print "\t(2)..."
                time.sleep(1)
                if h2.interrupted:
                    print "\t(2) interrupted!"
                    time.sleep(2)
                    break
        if h1.interrupted:
            print "(1) interrupted!"
            time.sleep(2)
            break

Von hier aus: https://gist.github.com/2907502

33voto

Jay Conrod Punkte 27696

Sie können mit CTRL + C durch das Einfangen der KeyboardInterrupt Ausnahme. Sie können jeglichen Bereinigungscode in den Exception-Handler implementieren.

32voto

Noch ein Schnipsel

Empfohlen main als Hauptfunktion und exit_gracefully als die CTRL + c Handler

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        pass
    finally:
        exit_gracefully()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X