在try块中使用return返回try/else

Sim*_*got 44 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)
print divide(1, 0)
Run Code Online (Sandbox Code Playgroud)

输出:

entering divide
exit
1
entering divide
error
exit
None
Run Code Online (Sandbox Code Playgroud)

else如果在返回值中,似乎python不会进入块内try.但是,它总会进入finally阻止.我真的不明白为什么.有人可以用这个逻辑来帮助我吗?

谢谢

wRA*_*RAR 56

http://docs.python.org/reference/compound_stmts.html#the-try-statement

如果控制流出try子句的末尾,则执行可选的else子句.

目前,除了异常或执行return,continue或break语句之外,控制"流出结束".

  • 遗憾的是,如果没有捕获到异常,则没有保证运行的 `else` 等效项,即使引发了 try `return`s 或未捕获的异常(这也会阻止 `else` 运行) (2认同)

Sau*_*aul 12

这种行为的原因是因为return内部try.

发生异常时,两个finallyexcept块之前都会执行return.在没有异常发生的相反情况下,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)
Run Code Online (Sandbox Code Playgroud)


Tim*_*ker 9

else块未执行,因为您在有机会之前已经离开了该函数.

但是,finally块总是被执行(除非你拉动电源线或类似的东西).

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

def whoops():
    try:
        return True
    finally:
        return False
Run Code Online (Sandbox Code Playgroud)

看看它返回的内容:

>>> whoops()
False
Run Code Online (Sandbox Code Playgroud)

如果你发现这令人困惑,你并不孤单.某些语言(如C#)会主动阻止您returnfinally子句中放置语句.

  • 对 C# 的评论+1。我对 else 和 finally 之间的逻辑差异感到困惑。这看起来像是一个困难的设计问题。 (2认同)

sam*_*sam 6

为什么该else条款不运行?

一个else条款是必须执行一些代码,如果try子句不引发异常

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

  • 当您调用 时divide(1, 1),该try子句成功运行,并返回。所以该else条款永远不会达成。


为什么finally子句总是运行?

一个finally子句离开try语句之前一直执行,是否已经发生也不例外。

看上面。


参考https://docs.python.org/3.5/tutorial/errors.html