2011-08-22 10 views
6

जब मेरा पायथन प्रोग्राम खत्म होता है तो मैं एक कार्य चलाने के लिए चाहता हूं, लेकिन केवल तभी सफलतापूर्वक समाप्त हो जाता है। जहां तक ​​मुझे पता है, एटएक्सिट मॉड्यूल का उपयोग करना है कि मेरा पंजीकृत फ़ंक्शन हमेशा सफलता की परवाह किए बिना प्रोग्राम समाप्ति पर चलाया जाएगा। क्या फ़ंक्शन पंजीकृत करने के लिए कोई समान कार्यक्षमता है ताकि यह केवल सफल निकास पर ही चल सके? वैकल्पिक रूप से, क्या मेरे निकास समारोह के लिए यह पता लगाने का कोई तरीका है कि बाहर निकलना सामान्य या असाधारण था या नहीं?मैं अपने पायथन कार्यक्रम के केवल * सफल * बाहर निकलने के लिए केवल एक फ़ंक्शन को कैसे पंजीकृत कर सकता हूं?

यहां कुछ कोड है जो समस्या का प्रदर्शन करता है। यह प्रिंट करेगा कि कार्यक्रम सफल हुआ, भले ही यह विफल हो गया हो।

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 नहीं कि आप क्या करना चाहते हैं के लिए काफी उपयुक्त है और बाहर निकलना। समानता के अनुसार, यह कोशिश करने/छोड़कर "आखिरकार" है, जबकि आप जो चाहते हैं वह एक कोशिश/छोड़कर "अन्य" है।

सबसे आसान तरीका मैं के बारे में सोच सकते हैं, जब तक कि यह एक वैश्विक ध्वज जो आप केवल सेट जब अपनी स्क्रिप्ट "सफल" सभी कार्यों आप atexit जाँच लें कि ध्वज को देते हैं बनाने के लिए ... और फिर है, और ऐसा कुछ भी नहीं जारी है सेट किया गया है

उदाहरण के लिए:

_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 

एक सीमा है, तो आप जो सफलता ध्वज सेट करने से पहले sys.exit(0) कॉल में कोई भी कोड है। इस तरह के कोड को पहले (मुख्य रूप से) मुख्य फ़ंक्शन पर वापस जाने के लिए दोबारा प्रतिक्रिया दी जानी चाहिए, ताकि आप set_success और sys.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। –