2012-03-16 10 views
11

Quiero saber si una secuencia de comandos de Python está terminando correctamente o no. Para esto estoy usando atexit pero el problema es que no sé cómo diferenciar si atexit fue llamado con sys.exit (0) o no cero o una excepción.¿Cómo encontrar el código de salida o el motivo cuando se llama a la llamada atexit en Python?

Razonamiento: si el programa finaliza correctamente, no hará nada más que si el programa finaliza con una excepción o devuelve un código de error (estado de salida) distinto de cero. Deseo activar alguna acción.

En caso de que se pregunte por qué no estoy utilizando try/finally es porque quiero agregar el mismo comportamiento para una docena de scripts que están importando un módulo común. En lugar de modificarlos a todos, quiero agregar el atexit() hack al módulo que se está importando y obtener este comportamiento de forma gratuita en todos ellos.

+0

¿Qué quieres lograr? ¿Por qué no solo usar el manejo correcto de errores? –

Respuesta

7

Usted puede conseguir resolver este usando sys.excepthook y mono-parches sys.exit():

import atexit 
import sys 

class ExitHooks(object): 
    def __init__(self): 
     self.exit_code = None 
     self.exception = None 

    def hook(self): 
     self._orig_exit = sys.exit 
     sys.exit = self.exit 
     sys.excepthook = self.exc_handler 

    def exit(self, code=0): 
     self.exit_code = code 
     self._orig_exit(code) 

    def exc_handler(self, exc_type, exc, *args): 
     self.exception = exc 

hooks = ExitHooks() 
hooks.hook() 

def foo(): 
    if hooks.exit_code is not None: 
     print("death by sys.exit(%d)" % hooks.exit_code) 
    elif hooks.exception is not None: 
     print("death by exception: %s" % hooks.exception) 
    else: 
     print("natural death") 
atexit.register(foo) 

# test 
sys.exit(1) 
+0

@sorin: Funciona bien para mí. Envolví las funciones de gancho en una clase (que no cambia la funcionalidad) y agregué el 'sys.exit (1)'. Imprime 'sys.exit (1)' para mí en Python 2.7. –

+0

@sorin: ¿Olvidaste quizás un 'global exit_code' dentro de' patched_exit'? Lo olvidé al principio, pero lo edité justo después de publicar la respuesta. –

+1

También funciona en Python 3. –

Cuestiones relacionadas