2011-08-22 3 views
6

필자의 파이썬 프로그램이 끝났을 때, 성공적으로 끝난 경우에만 작업을 실행하고 싶습니다. 내가 아는 한, atexit 모듈을 사용하면 등록한 함수가 항상이 성공에 관계없이 프로그램 종료시 실행된다는 것을 의미합니다. 성공적인 종료시에만 실행되도록 함수를 등록하는 비슷한 기능이 있습니까? 또는 출구 기능이 정상인지 아니면 예외인지를 감지 할 수있는 방법이 있습니까?Python 프로그램의 * successful * exit에서만 호출 할 수있는 함수를 어떻게 등록 할 수 있습니까?

다음은 문제를 나타내는 코드입니다. 프로그램이 실패한 경우에도 프로그램이 성공했음을 인쇄합니다.

import atexit 

def myexitfunc(): 
    print "Program succeeded!" 

atexit.register(myexitfunc) 

raise Exception("Program failed!") 

출력 :

박스의 아웃
$ python atexittest.py 
Traceback (most recent call last): 
    File "atexittest.py", line 8, in <module> 
    raise Exception("Program failed!") 
Exception: Program failed! 
Program succeeded! 

답변

4

, atexit 당신이 무엇을 원하는에 매우 적합하지 않다 : 그것은 주로 매우 마지막 순간에 자원 정리를 위해 사용되는 상황이 종료 될 때 종료. 비유하자면, 그것은 try/except의 "finally"입니다. 반면에 당신이 원하는 것은 try/except의 "else"입니다.

내가 생각할 수있는 가장 간단한 방법은 스크립트가 "성공"했을 때만 설정할 수있는 글로벌 플래그를 계속 만드는 것입니다. 그리고 나서 atexit에 첨부 된 모든 기능을 사용하여 해당 플래그를 확인하고 설정되었습니다.

예 : 당신이 성공 플래그를 설정하기 전에 sys.exit(0)를 호출하는 코드가있는 경우

_success = False 
def atsuccess(func, *args, **kwds): 
    def wrapper(): 
     if _success: 
      func(*args,**kwds) 
    atexit(wrapper) 

def set_success(): 
    global _success 
    _success = True 

# then call atsuccess() to attach your callbacks, 
# and call set_success() before your script returns 

한 가지 제한이 있습니다. 이러한 코드는 먼저 주 함수로 되돌아 가도록 리팩토링되어야하므로 set_successsys.exit을 한 곳에서만 호출 할 수 있습니다. 그 실패, 당신은 당신의 스크립트의 주요 항목 점을 중심으로 다음과 같은 래퍼 같은 것을 추가해야합니다하십시오 with 성명에서

try: 
    main() 
except SystemExit, err: 
    if err.code == 0: 
     set_success() 
    raise 
+0

이것은 아마도 내가 묻는 것을 얻는 가장 간단한 방법 일 것입니다. –

4

랩 프로그램의 몸과 만 작업을 수행 해당 컨텍스트 객체를 정의 예외가 제기되지 않은 경우. 다음과 같이 입력하십시오 :

class AtExit(object): 
    def __enter__(self): 
     return self 

    def __exit__(self, exc_type, exc_value, traceback): 
     if exc_value is None: 
      print "Success!" 
     else: 
      print "Failure!" 

if __name__ == "__main__": 
     with AtExit(): 
      print "Running" 
#   raise Exception("Error") 
+0

이것은 전체 프로그램의 끝 부분뿐만 아니라 프로그램의 일부를 종료 할 때 좋은 방법입니다. 유용한 패턴이므로 +1하십시오. –