2012-06-22 43 views
53

這是一些行爲特殊的代碼。這是我寫的行爲的簡化版本。這仍然會顯示出奇怪的行爲,並且我爲此發生了一些具體問題。奇怪的Try-Except-Else-最後的行爲與Return語句

我使用Python 2.6.6在Windows 7

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 

if __name__ == "__main__": 
    print "*** DEMO ONE ***" 
    print demo1() 
    print "****************" 
    print 
    print "*** DEMO TWO ***" 
    print demo2() 
    print "****************" 

當您運行此腳本,它將打印:

*** DEMO ONE *** 
3 
**************** 

*** DEMO TWO *** 
6 
3 
**************** 

爲什麼演示一個返回3而不是1? 爲什麼演示版本2打印6而不是打印6 w/4或5?

感謝您的幫助。

回答

80

因爲finally語句是保證被執行(當然,假設沒有停電或Python以外的任何控制)。這意味着在函數返回之前,它必須運行finally塊,它返回一個不同的值。

Python docs狀態:

當一回,打破或continue語句在一個try ... finally語句的try套件執行,finally子句也執行「的出路。」 finally語句中的continue語句是非法的。 (原因是目前的實施存在問題 - 將來可能會取消這一限制)。

這意味着當您嘗試返回時,將調用finally塊,返回它的值,而不是您將擁有的值。

+1

爲什麼在第二個例子中不打印5?我認爲這仍然沒有得到很好的解釋。返回一個很好回答,但爲什麼沒有在第二個例子中的5打印 –

+4

哦,我想我覺得它在最初的嘗試返回導致它立即跳轉到外部 –

+2

正是因爲'終於'塊**總是** 跑。 –

1

的執行順序是:

  1. try塊全部正常完成 - > finally塊 - >函數結束
  2. try塊運行,進入異常A - > finally塊 - >函數結束
  3. 嘗試塊做一個返回值並調用返回 - > finally塊 - >彈出返回值 - >函數結束

所以,finally塊中的任何返回將提前結束這些步驟。

+0

您可以使用列表格式作爲答案。 – gsamaras