¿Hay alguna forma en Python de capturar el KeyboardInterrupt
evento 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.
¿Hay alguna forma en Python de capturar el KeyboardInterrupt
evento 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.
Sí, puede instalar un manejador de interrupciones usando la señal del módulo y esperar eternamente usando un subproceso .
import signal
import sys
import time
import threading
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()
while True: continue
embargo, espero que nunca lo hagas . (En ese estilo,while True: pass
sería más ordenado, de todos modos.) Eso sería un desperdicio; intente algo comowhile True: time.sleep(60 * 60 * 24)
(dormir un día a la vez es una cifra completamente arbitraria).time
(como debería), no olvideimport time
:)Si todo lo que desea es no mostrar el rastreo, haga su código así:
(Sí, sé que esto no responde directamente a la pregunta, pero no está realmente claro por qué es objetable necesitar un bloque try / except; tal vez esto lo haga menos molesto para el OP)
fuente
signal.signal( signal.SIGINT, lambda s, f : sys.exit(0))
siempre lo hace.Una alternativa para configurar su propio controlador de señales es usar un administrador de contexto para detectar la excepción e ignorarla:
Esto elimina el bloque
try
-except
conservando 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 nuevamente los controladores de señal cada vez.
fuente
Sé que esta es una pregunta antigua, pero vine aquí primero y luego descubrí el
atexit
módulo. Todavía no conozco su historial multiplataforma o una lista completa de advertencias, pero hasta ahora es exactamente lo que estaba buscando al tratar de manejar post-KeyboardInterrupt
limpieza en Linux. Solo quería incluir otra forma de abordar el problema.Quiero hacer una limpieza posterior a la salida en el contexto de las operaciones de Fabric, por lo que envolver todo en
try
/except
tampoco era una opción para mí. me siento comoatexit
puede encajar bien en una situación así, en la que su código no está en el nivel superior de flujo de control.atexit
es muy capaz y legible desde el primer momento, por ejemplo:También puede usarlo como decorador (a partir de 2.6; este ejemplo es de los documentos):
Si quisiera hacerlo específico para
KeyboardInterrupt
solo , la respuesta de otra persona a esta pregunta probablemente sea mejor.Pero tenga en cuenta que el
atexit
módulo tiene 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 deatexit
eso garantizaría una versión modificada: actualmente no puedo concebir una forma de que las funciones de devolución de llamada de salida conozcan las excepciones;atexit
controlador detecta la excepción, llama a su devolución de llamada y luego vuelve a generar esa excepción. Pero podría hacerlo de otra manera).Para obtener más información, consulte:
atexit
fuente
Puede evitar la impresión de un seguimiento de pila para
KeyboardInterrupt
, sintry: ... except KeyboardInterrupt: pass
(la solución más obvia y probablemente "mejor", pero ya la sabe y pidió algo más) reemplazandosys.excepthook
. Algo comofuente
Probé las soluciones sugeridas por todos, pero tuve que improvisar el código para que funcionara. A continuación está mi código improvisado:
fuente
Si alguien está buscando una solución mínima rápida,
fuente