2012-03-16 13 views
11

Chcę wiedzieć, czy skrypt w języku Python kończy się poprawnie, czy nie. Do tego używam atexit, ale problem polega na tym, że nie wiem, jak rozróżnić, czy został wywołany atexit z sys.exit (0) lub niezerowy lub wyjątek.Jak znaleźć kod wyjścia lub powód, gdy wywołanie zwrotne atexit jest wywoływane w Pythonie?

Powód: jeśli program zakończy się poprawnie, nie zrobi nic, tylko jeśli program zakończy się wyjątkiem lub zwróci kod błędu (status wyjścia) inny niż zero. Chcę wywołać pewne działanie.

Jeśli zastanawisz się, dlaczego nie używam metody try/finally, to chcę dodać to samo zachowanie dla kilkunastu skryptów importujących wspólny moduł. Zamiast modyfikować wszystkie z nich, chcę dodać atexit() do importowanego modułu i uzyskać to zachowanie za darmo we wszystkich z nich.

+0

Co chcesz osiągnąć? Dlaczego nie po prostu użyć właściwej obsługi błędów? –

Odpowiedz

7

można dostać rozwiązać ten problem za pomocą sys.excepthook i przez małpa-łatanie 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: To działa dobrze dla mnie. Zawinęłem funkcje przechwytujące w klasie (która nie zmienia funkcjonalności) i dodano 'sys.exit (1)'. Wydaje 'sys.exit (1)' dla mnie w Pythonie 2.7. –

+0

@sorin: Czy możesz zapomnieć o 'global exit_code' w' patched_exit'? Z początku o tym zapomniałem, ale zredagowałem to zaraz po opublikowaniu odpowiedzi. –

+1

Działa również na Pythonie 3. –

Powiązane problemy