अजीब कोशिश-अपवाद-एल्स-अंत में रिटर्न स्टेटमेंट के साथ व्यवहार


91

यह कुछ कोड है जो अजीबोगरीब व्यवहार कर रहा है। यह मेरे द्वारा लिखे गए व्यवहार का एक सरलीकृत संस्करण है। यह अभी भी अजीब व्यवहार प्रदर्शित करेगा और मेरे कुछ विशिष्ट प्रश्न थे कि ऐसा क्यों हो रहा है।

मैं विंडोज 7 पर पायथन 2.6.6 का उपयोग कर रहा हूं।

def demo1():
    try:
        raise RuntimeError,"To Force Issue"
    except:
        return 1
    else:
        return 2
    finally:
        return 3

def demo2():
    try:
        try:
            raise RuntimeError,"To Force Issue"
        except:
            return 1
        else:
            return 2
        finally:
            return 3
    except:
        print 4
    else:
        print 5
    finally:
        print 6

परिणाम:

>>> print demo1()
3
>>> print demo2()
6
3
  • डेमो 1 के बजाय 3 रिटर्न क्यों कर रहा है?
  • डेमो दो प्रिंटिंग 6 को 6 w / 4 या 5 के बजाय प्रिंट करने के लिए क्यों है?

जवाबों:


128

क्योंकि finallyबयानों को निष्पादित करने की गारंटी दी जाती है (अच्छी तरह से, कोई बिजली आउटेज या पायथन के नियंत्रण के बाहर कुछ भी नहीं)। इसका मतलब यह है कि फ़ंक्शन लौटने से पहले, इसे अंततः ब्लॉक को चलाना होगा, जो एक अलग मान लौटाता है।

अजगर डॉक्स राज्य:

जब रिटर्न, ब्रेक या जारी स्टेटमेंट को एक कोशिश के ट्रायल सूट में निष्पादित किया जाता है ... अंत में स्टेटमेंट, अंत में क्लॉज को 'बाहर निकलने के तरीके' पर भी निष्पादित किया जाता है।

किसी फ़ंक्शन का वापसी मान निष्पादित अंतिम रिटर्न स्टेटमेंट द्वारा निर्धारित किया जाता है। चूंकि अंतिम खंड हमेशा निष्पादित होता है, इसलिए अंतिम खंड में निष्पादित विवरण हमेशा अंतिम निष्पादित होगा:

इसका मतलब यह है कि जब आप लौटने की कोशिश करते हैं, तो finallyब्लॉक को बुलाया जाता है, जो आपके पास होता है, बजाय इसके मूल्य को वापस करना।


4
दूसरे उदाहरण में 5 प्रिंट क्यों नहीं करता है? यह अभी भी अच्छी तरह से समझाया गया है मुझे नहीं लगता है। रिटर्न एक अच्छी तरह से उत्तर दिया गया है, लेकिन दूसरे उदाहरण के प्रिंट में 5 क्यों नहीं है
जोरन बेज़ले

5
ओह, मुझे लगता है कि मुझे लगा कि यह शुरुआती कोशिश में वापसी का कारण बनता है, यह तुरंत बाहरी रूप से कूदने का कारण बनता है
जोरन बेज़ले

2
बिल्कुल, क्योंकि finallyब्लॉक हमेशा चलते हैं।
गारेथ लैटी

2
डेमो दो में, यह आखिरकार नेस्टेड को निष्पादित क्यों करता है, बाहर से किक करें आखिरकार नेस्टेड में वापस जाएं आखिरकार रिटर्न खत्म करने के बजाय बस बाहर से कोई नहीं लौटा?
काइल ने

1
क्योंकि जब returnवक्तव्य को बुलाया जाता है, तो पायथन किसी भी खुले finallyखंड की जांच करता है जिसे निष्पादित करने की आवश्यकता होती है (ऊपर उद्धरण देखें)।
गारेथ लैटी

7

निष्पादन आदेश है:

  1. ब्लॉक को सामान्य रूप से पूरा करने की कोशिश करें -> अंत में ब्लॉक -> फ़ंक्शन समाप्त होता है
  2. ब्लॉक रन का प्रयास करें और अपवाद में जाएं -> अंत में ब्लॉक -> फ़ंक्शन समाप्त होता है
  3. ब्लॉक को रिटर्न वैल्यू बनाने की कोशिश करें और रिटर्न कॉल करें -> अंत में ब्लॉक -> पॉपअप रिटर्न वैल्यू -> फ़ंक्शन समाप्त होता है

तो, अंत में ब्लॉक में किसी भी वापसी अग्रिम में कदम समाप्त हो जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.