Python try/else在try块中返回

Python try/else在try块中返回,python,exception-handling,Python,Exception Handling,我在python中遇到了一个奇怪的行为。我在python帮助或SE上找不到有关这方面的信息,因此如下所示: def divide(x, y): print 'entering divide' try: return x/y except: print 'error' else: print 'no error' finally: print 'exit' print divide(1, 1)

我在python中遇到了一个奇怪的行为。我在python帮助或SE上找不到有关这方面的信息,因此如下所示:

def divide(x, y):
    print 'entering divide'
    try:
        return x/y
    except:
        print 'error'
    else:
        print 'no error'
    finally:
        print 'exit'

print divide(1, 1)
print divide(1, 0)
输出:

entering divide
exit
1
entering divide
error
exit
None
如果在
try
中返回值,python似乎不会进入
else
块。但是,它将始终进入
finally
块。我真的不明白为什么。有人能帮我解释一下这个逻辑吗

谢谢

当控制流离开时,将执行可选的else子句 try子句的结尾

目前,控制“从末端流出”,但在以下情况除外: 异常或执行return、continue或break语句


“return”结束函数并返回您希望它返回的任何内容。所以它当然不会继续下去。“finally”总是被执行

出现这种行为的原因是
内的
返回
try

当异常发生时,
finally
except
块在
返回之前执行。在没有发生异常的相反情况下,
else
运行而
except
不运行

这与预期的效果一样:

def divide(x, y):
    print 'entering divide'
    result = 0
    try:
        result = x/y
    except:
        print 'error'
    else:
        print 'no error'
    finally:
        print 'exit'

    return result

print divide(1, 1)
print divide(1, 0)

else
块未执行,因为您在函数有机会离开之前就离开了它

但是,始终会执行
finally
块(除非您拔掉电源线或类似的东西)

考虑这一点(作为一个思维实验;请不要在实际代码中这样做):

查看它返回的内容:

>>> whoops()
False

如果你感到困惑,你并不孤单。有些语言,如C#,会主动阻止您在
finally
子句中放置
return
语句

为什么
else
子句不运行?

如果try子句未引发异常,则必须执行的代码可以使用
else
子句

  • 调用
    divide(1,0)
    时,您的
    try
    子句会引发异常
    ZeroDivisionError
    ,因此
    else
    子句不会运行

  • 调用
    divide(1,1)
    时,
    try
    子句将成功运行并返回。因此,
    else
    子句永远不会到达


为什么总是运行
finally
子句?

无论是否发生异常,
finally
子句总是在离开try语句之前执行

见上文



有关C#的评论,请参考

+1。我对else和finally之间的逻辑差异感到困惑。这看起来是一个很难解决的设计问题。+1用于突出显示返回值,可以设置两次!在实际代码中,这肯定是个坏主意。无论如何,限制
return
raise
的数量始终是一个好主意,因为它澄清了代码输出。实际上,
try
的返回也有效。所发生的是
try
的return语句runs'AFTER'最终运行。这里@tim在
try
中首先使用了
return
2次,在
中使用了其他方法,最后使用了
。由于
try
的返回在finally块之后执行,finally已经有了自己的返回!因此,
最终
的返回将运行,而“原始”
try
的返回从未得到运行的更改!哈,终于是如此强大!遗憾的是,即使try
返回
s或引发了未捕获的异常(这也会停止
else
运行),如果未捕获异常,也没有保证运行的
else
等效程序
>>> whoops()
False