Hay alguna forma de ejecutar un último comando antes de ejecutar secuencia de comandos de Python es detenido por ser asesinado por algún otro script, interrupción de teclado, etc.

InformationsquelleAutor dan | 2009-05-30

5 Comentarios

  1. 33
    import time
    
    try:
        time.sleep(10)
    finally:
        print "clean up"
    
    clean up
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
    KeyboardInterrupt

    Si usted necesita tomar otro sistema operativo a nivel de las interrupciones, la mirada en el módulo de señal:

    http://docs.python.org/library/signal.html

    Señal De Ejemplo

    from signal import *
    import sys, time
    
    def clean(*args):
        print "clean me"
        sys.exit(0)
    
    for sig in (SIGABRT, SIGBREAK, SIGILL, SIGINT, SIGSEGV, SIGTERM):
        signal(sig, clean)
    
    time.sleep(10)
    • No tengo idea de por qué eligió ese conjunto particular, pero SIGBREAK no funciona en Windows no Pitones, y SIGILL son SIGSEGV probablemente no son señales de que desea ser reventado sin una muy buena razón.
    • es sólo un ejemplo. Y su dan para decidir lo que se interrumpe quiere trampa.
    • Es sys.exit(0) necesario? Pensé python sale después de que su función terminado de todos modos. Se utiliza para mostrar que es una manejado?
    • -1 para el extraño y arbitrario conjunto de señales, como se nota por @Dave. El uso de SIGTERM tendría sentido (puesto que su propósito es instruir a los procesos de salida), y el uso de SIGUSR1 sería defendible (ya sea por acciones definidas por el usuario), pero tener cosas como SIGILL no es simplemente ilógico. Además, esto sólo parcialmente responde a la pregunta; no tratar el caso en que el guión es asesinado por una interrupción de teclado, que era una posibilidad incluidos en la pregunta.
  2. 11

    Podría utilizar el atexit módulo. Con él, usted puede registrar una función que será llamada en la terminación del programa. Un ejemplo de aquí: http://docs.python.org/library/atexit.html

    try:
        _count = int(open("/tmp/counter").read())
    except IOError:
        _count = 0
    
    def incrcounter(n):
        global _count
        _count = _count + n
    
    def savecounter():
        open("/tmp/counter", "w").write("%d" % _count)
    
    import atexit
    atexit.register(savecounter)

    También puede pasar de la posición de la palabra clave de parámetros a la función que desea llamar en la terminación del programa.

    Nota que hay un par de circunstancias que se citan en los documentos en los que el controlador no será llamado:

    Nota: Las funciones registrados a través de este módulo no se llama cuando el programa es asesinado por una señal que no se maneja por Python, cuando un Python interna fatal error es detectado, o cuando os._exit() se llama.

    Como tal, puede que también desee registrar un manejador de señal.

  3. 8
    import signal
    import sys
    import time
    
    def cleanup(*args):
        print 'Exiting'
        sys.exit(0)
    
    signal.signal(signal.SIGINT, cleanup)
    signal.signal(signal.SIGTERM, cleanup)
    while True:
        time.sleep(60)  # less busy loop
    • Nota: aunque exit() no es async-caja fuerte en la C, la redacción de la documentación de Python me sugiere que Python se ocupa de este problema con alguna señal especial-código de manipulación.
    • He probado este código en Windows XP, y un error es en realidad debido tiempo.sleep() se ha interrumpido. Funciona en GNU/Linux.
  4. 6

    Con el perdón de los ‘Desconocidos’ para tomar su respuesta y corregir es como si fuera mi propia respuesta, pero mis ediciones fueron rechazadas.

    La aprobación de respuesta contiene un error que va a causar una violación de segmento.

    Usted puede utilizar sys.exit() en un manejador de señal, pero usted puede usar el sistema operativo._exit por lo que se convierte en:

    from signal import *
    import os, time
    
    def clean(*args):
        print "clean me"
        os._exit(0)
    
    for sig in (SIGABRT, SIGINT, SIGTERM):
        signal(sig, clean)
    
    time.sleep(10)

    SIGBREAK pueden ser utilizadas si el objetivo de la plataforma es Windows.

    Dependiendo del caso de uso y la necesidad de limpieza en caso de errores fatales – usted puede agregar SIGSEGV y SIGILL pero en general esto no es aconsejable ya que el estado del programa puede ser tal que se crea un bucle infinito.

    • «La aprobación de respuesta contiene un error que va a causar una violación de segmento.» – ¿cuál es el error? El uso de sys.exit()? No violación de segmento para mí; ¿qué tengo que hacer para ver esta violación de segmento? «no Se puede utilizar sys.exit() en un manejador de señal» – parece que funciona para mí; ¿cuál es tu base para esto? Un cauteloso -1, por ahora ya que la clave de reclamaciones en esta respuesta son infundadas.
    • El accidente no es garantizado, básicamente, el comportamiento de la recaudación de la excepción de sys.exit() es indefinido. Diferentes conductas que se han visto incluyen estrellarse (stackoverflow.com/questions/24789269/…) o la salida de la llamada simplemente que aparece no funciona en absoluto (stackoverflow.com/questions/29980078/…). Véase también thushw.blogspot.co.reino unido/2010/12/…
    • Usted también no reconoce mis comentarios sobre SIGSEGV/SIGILL que también son incorrectos en respuesta.
    • parece probable que el problema en el que los blog fue causado por el desnudo except: la captura de la SystemExit. Por favor, ¿podría usted ampliar lo que quieres decir por «el comportamiento de la recaudación de la excepción de sys.exit() no está definido»? No estoy seguro de entender.
  5. 3

    Utilizar el atexit módulo para registrar una función que se llama en la final.

    import atexit
    atexit.register(some_function)
    • No funciona en la interrupción de teclado.

Dejar respuesta

Please enter your comment!
Please enter your name here