使用Return语句的奇怪的Try-Except-Else-Finally行为

时间:2012-06-22 21:07:36

标签: python try-except

这是一些表现特殊的代码。这是我编写的行为的简化版本。这仍然会表现出奇怪的行为,并且我对于为什么会这样做有一些具体的问题。

我在Windows 7上使用Python 2.6.6。

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

结果:

>>> print demo1()
3
>>> print demo2()
6
3
  • 为什么demo 1会返回3而不是1?
  • 为什么演示两次打印6而不是打印6 w / 4或5?

3 个答案:

答案 0 :(得分:101)

因为finally语句保证被执行(好吧,假设没有停电或Python控制之外的任何事情)。这意味着在函数返回之前,它必须运行finally块,它返回一个不同的值。

Python docs州:

  

当在try ... finally语句的try套件中执行return,break或continue语句时,finally子句也会在出路时执行。在continue子句中,continue语句是非法的。 (原因是当前实施存在问题 - 将来可能会解除此限制。)

这意味着当您尝试返回时,会调用finally块,返回它的值,而不是您应该拥有的值。

答案 1 :(得分:5)

执行顺序是:

  1. 尝试阻止所有正常完成 - >最后阻止 - >功能结束
  2. 尝试阻止运行并进入例外A - >最后阻止 - >功能结束
  3. 尝试阻止返回值并调用return - >最后阻止 - >弹出返回值 - >功能结束
  4. 因此,finally块中的任何返回都将提前结束这些步骤。

答案 2 :(得分:1)

请注意,已经有 PEP601 禁止来自 finally 子句的 return 语句,但它已被拒绝。 但是,PEP8 中的样式指南已添加应避免使用。