from error python keyboardinterrupt

error - Capture el tecladointerrumpido en Python sin intentarlo, excepto



raise python (5)

¿Hay alguna forma en Python para capturar el evento KeyboardInterrupt sin poner todo el código dentro de una declaración try - except ? Quiero salir limpiamente sin dejar rastro si el usuario presiona ctrl - c .


Puede evitar la impresión de un seguimiento de pila para KeyboardInterrupt , sin try: ... except KeyboardInterrupt: pass (la solución más obvia y probablemente la "mejor", pero ya lo sabe y le pidió otra cosa) al reemplazar sys.excepthook . Algo como

def custom_excepthook(type, value, traceback): if type is KeyboardInterrupt: return # do nothing else: sys.__excepthook__(type, value, traceback)


Sé que esta es una vieja pregunta, pero vine aquí primero y luego descubrí el módulo atexit . Aún no conozco su historial de plataforma cruzada o una lista completa de advertencias, pero hasta ahora es exactamente lo que estaba buscando para tratar de manejar la limpieza posterior a KeyboardInterrupt en Linux. Solo quería arrojar otra forma de abordar el problema.

Quiero hacer una limpieza posterior a la salida en el contexto de las operaciones Fabric, por lo que envolver todo en try / except tampoco era una opción para mí. Siento que atexit puede ser una buena atexit en una situación en la que el código no está en el nivel superior del flujo de control.

atexit es muy capaz y legible de atexit , por ejemplo:

import atexit def goodbye(): print "You are now leaving the Python sector." atexit.register(goodbye)

También puede usarlo como decorador (a partir de 2.6; este ejemplo es de los documentos):

import atexit @atexit.register def goodbye(): print "You are now leaving the Python sector."

Si desea que sea específico para KeyboardInterrupt solo, la respuesta de otra persona a esta pregunta es probablemente mejor.

Pero tenga en cuenta que el módulo atexit es solo ~ 70 líneas de código y no sería difícil crear una versión similar que trate las excepciones de manera diferente, por ejemplo, pasando las excepciones como argumentos a las funciones de devolución de llamada. (La limitación de atexit que justificaría una versión modificada: actualmente no puedo concebir una forma para que las funciones atexit -exit conozcan las excepciones; el controlador atexit capta la excepción, llama a su (s) devolución de llamada (s), luego re - levanta esa excepción. Pero podrías hacer esto de otra manera).

Para obtener más información, consulte:


Sí, puede instalar un manejador de interrupciones usando la signal del módulo y esperar por siempre con un threading.Event . threading.Event :

import signal import sys import time def signal_handler(signal, frame): print(''You pressed Ctrl+C!'') sys.exit(0) signal.signal(signal.SIGINT, signal_handler) print(''Press Ctrl+C'') forever = threading.Event() forever.wait()


Si todo lo que quiere es no mostrar el rastreo, haga su código así:

## all your app logic here def main(): ## whatever your app does. if __name__ == "__main__": try: main() except KeyboardInterrupt: # do nothing here pass

(Sí, sé que esto no responde directamente a la pregunta, pero no está muy claro por qué es objetable tener que probar / except bloquear; quizás esto sea menos molesto para el OP)


Una alternativa para configurar su propio manejador de señal es usar un gestor de contexto para capturar la excepción e ignorarla:

>>> class CleanExit(object): ... def __enter__(self): ... return self ... def __exit__(self, exc_type, exc_value, exc_tb): ... if exc_type is KeyboardInterrupt: ... return True ... return exc_type is None ... >>> with CleanExit(): ... input() #just to test it ... >>>

Esto elimina el bloque try - except preservando alguna mención explícita de lo que está sucediendo.

Esto también le permite ignorar la interrupción solo en algunas partes de su código sin tener que configurar y restablecer de nuevo los manejadores de señal cada vez.