Python異常捕捉try except else finally有return時執行順序探究

來源:互聯網
上載者:User

標籤:dex   run   第一條   size   visio   toolbar   並且   str   return語句   

轉載自 https://www.cnblogs.com/JohnABC/p/4065437.html

學習python或者其他有異常控制的編程語 言, 大家很有可能說try except finally(try catch finally)的執行很簡單,無非就是有異常的話執行except, finally無論是否有異常都會執行, 大致上原則是這樣, 但是如果涉及到更加詳細的複雜的路徑,加上return 語句,就沒有那麼簡單了。

1. 沒有return 語句的情況

print ‘this is a test of code path in try...except...else...finally‘print ‘************************************************************‘ def exceptTest():    try:        print ‘doing some work, and maybe exception will be raised‘        raise IndexError(‘index error‘)        #print ‘after exception raise‘        #return 0             except KeyError, e:        print ‘in KeyError except‘        print e        #return 1    except IndexError, e:        print ‘in IndexError except‘        print e        #return 2    except ZeroDivisionError, e:        print ‘in ZeroDivisionError‘        print e        #return 3    else:        print ‘no exception‘        #return 4    finally:        print ‘in finally‘        #return 5 resultCode = exceptTest()print resultCode
上面的代碼是一直要使用的代碼,只不過暫時不用的代碼被comment了。

有異常發生,並且捕獲異常,最後在finally進行處理,上面代碼的輸出:

this is a test of code path in try...except...else...finally************************************************************doing some work, and maybe exception will be raisedin IndexError exceptindex errorin finallyNone

然後我們逐漸給上面代碼各個情況添加return 語句, 查看添加return 語句後的代碼執行效果。

2. 添加return 語句的情況

print ‘this is a test of code path in try...except...else...finally‘print ‘************************************************************‘ def exceptTest():    try:        print ‘doing some work, and maybe exception will be raised‘        raise IndexError(‘index error‘)        print ‘after exception raise‘        return 0             except KeyError, e:        print ‘in KeyError except‘        print e        return 1    except IndexError, e:        print ‘in IndexError except‘        print e        return 2    except ZeroDivisionError, e:        print ‘in ZeroDivisionError‘        print e        return 3    else:        print ‘no exception‘        return 4    finally:        print ‘in finally‘        return 5 resultCode = exceptTest()print resultCode

這個時候所有的分支都存在return 語句,並且會引發異常, 看一下輸出:

this is a test of code path in try...except...else...finally************************************************************doing some work, and maybe exception will be raisedin IndexError exceptindex errorin finally5

異常發生後,raise語句以後的不再執行,然後到了捕獲異常語句, 但是捕獲異常模組有個return , 是不是這個時候就不再繼續執行直接返回呢?但是這是跟 finally語句必然執行是相衝突的, 可以在結果中看到finally實際上執行了,並且傳回值是5,在 finally de 的傳回值。

然後,我們在看看把finally 的傳回值注釋掉,看看傳回值是多少?

代碼如下:

print ‘this is a test of code path in try...except...else...finally‘print ‘************************************************************‘ def exceptTest():    try:        print ‘doing some work, and maybe exception will be raised‘        raise IndexError(‘index error‘)        print ‘after exception raise‘        return 0             except KeyError, e:        print ‘in KeyError except‘        print e        return 1    except IndexError, e:        print ‘in IndexError except‘        print e        return 2    except ZeroDivisionError, e:        print ‘in ZeroDivisionError‘        print e        return 3    else:        print ‘no exception‘        return 4    finally:        print ‘in finally‘        #return 5 resultCode = exceptTest()print resultCode

這個時候的程式輸出:

this is a test of code path in try...except...else...finally************************************************************doing some work, and maybe exception will be raisedin IndexError exceptindex errorin finally2

傳回值變為2, 這個時候有點疑惑了, 先不用解釋問題,我們繼續看其他的情況。

3. 沒有異常發生且try語句塊沒有return

代碼如下:

print ‘this is a test of code path in try...except...else...finally‘print ‘************************************************************‘ def exceptTest():    try:        print ‘doing some work, and maybe exception will be raised‘        #raise IndexError(‘index error‘)        print ‘after exception raise‘        #return 0             except KeyError, e:        print ‘in KeyError except‘        print e        return 1    except IndexError, e:        print ‘in IndexError except‘        print e        return 2    except ZeroDivisionError, e:        print ‘in ZeroDivisionError‘        print e        return 3    else:        print ‘no exception‘        return 4    finally:        print ‘in finally‘        return 5 resultCode = exceptTest()print resultCode

這個時候的代碼輸出:

this is a test of code path in try...except...else...finally************************************************************doing some work, and maybe exception will be raisedafter exception raiseno exceptionin finally5

這裡驗證了如果沒有異常那麼else語句是執行的,並且finally語句執行,然後返回finally語句的return 5

但是,當try語句塊裡存在return語句是什麼情況呢?

4. 沒有異常發生且try語句塊 存在return語句

print ‘this is a test of code path in try...except...else...finally‘print ‘************************************************************‘ def exceptTest():    try:        print ‘doing some work, and maybe exception will be raised‘        #raise IndexError(‘index error‘)        print ‘after exception raise‘        return 0             except KeyError, e:        print ‘in KeyError except‘        print e        return 1    except IndexError, e:        print ‘in IndexError except‘        print e        return 2    except ZeroDivisionError, e:        print ‘in ZeroDivisionError‘        print e        return 3    else:        print ‘no exception‘        return 4    finally:        print ‘in finally‘        return 5 resultCode = exceptTest()print resultCode

執行結果:

this is a test of code path in try...except...else...finally************************************************************doing some work, and maybe exception will be raisedafter exception raisein finally5

這裡else沒有執行,和我們對於書本知識有衝突了, finally語句執行並返回5.

分析: 這裡因為沒有發生異常, 所以會執行到try塊中的return 語句,但是finally又必須執行,所以執行try中return 之前去執行了finally語句,並且可以認為,finally語句修改了最後返回的值,將try中的傳回值修改為5並最終返回,所以else語句並沒有 得到執行。

5. 有異常發生並且finally 沒有return 語句

print ‘this is a test of code path in try...except...else...finally‘print ‘************************************************************‘ def exceptTest():    try:        print ‘doing some work, and maybe exception will be raised‘        raise IndexError(‘index error‘)        print ‘after exception raise‘        return 0             except KeyError, e:        print ‘in KeyError except‘        print e        return 1    except IndexError, e:        print ‘in IndexError except‘        print e        return 2    except ZeroDivisionError, e:        print ‘in ZeroDivisionError‘        print e        return 3    else:        print ‘no exception‘        return 4    finally:        print ‘in finally‘        #return 5 resultCode = exceptTest()print resultCode

執行結果:

this is a test of code path in try...except...else...finally************************************************************doing some work, and maybe exception will be raisedin IndexError exceptindex errorin finally2

因為有異常發生,所以try中的return語句肯定是執行不到的,然後在捕獲到的except中進行執行,並且except中存在return 語句,那麼是不是就直接返回? 因為finally 語句是必須要執行的,所以這裡的return語句需要先暫且放下,進入finally進行執行,然後finnaly執行完以後再返回到 except中進行執行。

看到這裡,我們貌似找到了一些規律

1. 如果沒有異常發生, try中有return 語句, 這個時候else塊中的代碼是沒有辦法執行到的, 但是finally語句中如果有return 語句會修改最終的傳回值, 我個人理解的是try中return 語句先將要返回的值放在某個 CPU寄存器,然後運行finally語句的時候修改了這個寄存器的值,最後在返回到try中的return語句返回修改後的值。

2. 如果沒有異常發生, try中沒有return語句,那麼else塊的代碼是執行的,但是如果else中有return, 那麼也要先執行finally的代碼, 傳回值的修改與上面一條一致。

3. 如果有異常發生,try中的return語句肯定是執行不到, 在捕獲異常的 except語句中,如果存在return語句,那麼也要先執行finally的代碼,finally裡面的代碼會修改最終的傳回值,然後在從 except 塊的retrun 語句返回最終修改的傳回值, 和第一條一致。

轉自:http://www.2cto.com/kf/201405/304975.html

Python異常捕捉try except else finally有return時執行順序探究

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.