2008-10-06 13 views
39

दस्तावेज़ कहते हैं कि sys.exit() को कॉल करना SystemExit अपवाद उठाता है जिसे बाहरी स्तरों में पकड़ा जा सकता है। मेरे पास एक ऐसी स्थिति है जिसमें मैं निश्चित रूप से और निर्विवाद रूप से एक परीक्षण मामले के अंदर से बाहर निकलना चाहता हूं, हालांकि सबसे अजीब मॉड्यूल SystemExit को पकड़ता है और बाहर निकलने से रोकता है। यह सामान्य रूप से महान होता है, लेकिन विशिष्ट स्थिति जिसे मैं संभालने की कोशिश कर रहा हूं वह वह है जहां हमारे परीक्षण ढांचे ने पाया है कि यह एक गैर-परीक्षण डेटाबेस को इंगित करने के लिए कॉन्फ़िगर किया गया है। इस मामले में मैं बाहर निकलने और किसी और परीक्षण को चलाने से रोकना चाहता हूं। बेशक जब से सिस्टमटेक्सिट unittest जाल और इस तरह से खुशी से जारी है, यह मुझे परेशान कर रहा है।क्या sys.exit() से पकड़े गए SystemExit अपवाद को पकड़े जाने से रोकने का कोई तरीका है?

एकमात्र विकल्प जिसे मैंने अभी तक सोचा है, सीटीपीएस या कॉल एक्जिट (3) के समान कुछ का उपयोग कर रहा है, लेकिन यह वास्तव में सरल होना चाहिए जो कुछ के लिए एक सुंदर फगली हैक जैसा लगता है।

+0

यह एक एम्बेडेड आईपीथन शेल से प्रोग्राम से बाहर निकलने का प्रयास करते समय भी प्रासंगिक है। – quazgar

उत्तर

54

आप os._exit() फोन सीधे, बाहर निकलने के लिए एक अपवाद फेंकने के बिना कर सकते हैं:

import os 
os._exit(1) 

इस तरह के atexit मॉड्यूल के रूप में अजगर बंद तर्क के सभी, नजरअंदाज, और अपवाद हैंडलिंग तर्क के माध्यम से नहीं चलेगा कि आप इस स्थिति में से बचने की कोशिश कर रहे हैं। तर्क निकास कोड है जो प्रक्रिया द्वारा वापस किया जाएगा।

38

जैसा कि जेरुब ने कहा, os._exit(1) आपका उत्तर है। लेकिन, इस पर विचार करते हुए सभी सफाई प्रक्रियाएं, finally: ब्लॉक, फाइलें बंद करना आदि शामिल हैं, और वास्तव में सभी लागतों से बचा जाना चाहिए, क्या मैं इसका उपयोग करने के लिए "सुरक्षित-आश" तरीका पेश कर सकता हूं?

यदि आप समस्या SystemExit बाहरी स्तर (यानी, unittest) पर पकड़े जा रहे हैं, तो बाहरी स्तर स्वयं बनें! अपने मुख्य कोड को एक कोशिश/ब्लॉक को छोड़कर, सिस्टमएक्सिट को पकड़ें, और वहां os._exit पर कॉल करें, और केवल! इस तरह आप कोड में कहीं भी sys.exit को कॉल कर सकते हैं, इसे शीर्ष स्तर पर बुलबुला कर दें, सभी फ़ाइलों को गर्व से बंद करें और सभी क्लीनअप चलाएं, और फिर os._exit को कॉल करें।

आप यह भी चुन सकते हैं कि कौन से निकास "आपातकालीन" हैं। नीचे दिया गया कोड इस तरह का दृष्टिकोण है:

import sys, os 

EMERGENCY = 255 # can be any number actually 

try: 
    # wrap your whole code here ... 
    # ... some code 
    if x: sys.exit() 
    # ... some more code 
    if y: sys.exit(EMERGENCY) # use only for emergency exits 
    # ... 
except SystemExit as e: 
    if e.code != EMERGENCY: 
     raise # normal exit, let unittest catch it 
    else: 
     os._exit(EMERGENCY) # try to stop *that*, sucker! 
+1

एक मामला मुझे जांचने की आवश्यकता है यदि कोड 0 है, जो इंगित करता है कि हम बिना त्रुटि/क्रैशिंग के सामान्य रूप से बाहर निकलने का प्रयास कर रहे हैं। ऑप्शन पार्सर का उपयोग करते समय यह उपयोगी होता है जब यह पास हो जाता है -ह तर्क और मैं नहीं चाहता कि सिस्टमएक्सिट को अपवाद की तरह माना जाए। तो, धन्यवाद, आपने अपवाद के माध्यम से निकास कोड तक पहुंचने के तरीके को सत्यापित करने में मेरी सहायता की। – leetNightshade

+0

वही यहाँ। मुझे कोड 0 की जांच करने की आवश्यकता थी, और इससे मदद मिली। – BuvinJ

संबंधित मुद्दे