Ich schreibe ein Befehlszeilenprogramm in Python, das, da es sich um Produktionscode handelt, sauber heruntergefahren werden sollte, ohne eine Reihe von Dingen (Fehlercodes, Stapelspuren usw.) auf den Bildschirm zu werfen. Dies bedeutet, dass ich Tastaturinterrupts abfangen muss.
Ich habe versucht, beide einen try catch-Block zu verwenden, wie:
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print 'Interrupted'
sys.exit(0)
und das Signal selbst abfangen (wie in diesem Beitrag ):
import signal
import sys
def sigint_handler(signal, frame):
print 'Interrupted'
sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)
Beide Methoden scheinen im normalen Betrieb recht gut zu funktionieren. Wenn der Interrupt jedoch während des Bereinigungscodes am Ende der Anwendung auftritt, scheint Python immer etwas auf dem Bildschirm zu drucken. Das Fangen des Interrupts gibt
^CInterrupted
Exception KeyboardInterrupt in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802852b90>> ignored
wohingegen die Handhabung des Signals entweder ergibt
^CInterrupted
Exception SystemExit: 0 in <Finalize object, dead> ignored
oder
^CInterrupted
Exception SystemExit: 0 in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802854a90>> ignored
Diese Fehler sind nicht nur hässlich, sie sind auch nicht sehr hilfreich (insbesondere für Endbenutzer ohne Quellcode)!
Der Bereinigungscode für diese Anwendung ist ziemlich groß, daher besteht eine gute Chance, dass dieses Problem von echten Benutzern auftritt. Gibt es eine Möglichkeit, diese Ausgabe abzufangen oder zu blockieren, oder muss ich mich nur damit befassen?
sys.stdout
/sys.stderr
? Wiesys.stderr = open(os.devnull, 'w')
? Wenn Sie sich wirklich nicht für die endgültige Ausgabe interessieren, scheint dies die offensichtliche Lösung zu sein.