2012-06-22 44 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