【问题标题】:Weird Try-Except-Else-Finally behavior with Return statementsReturn 语句的奇怪 Try-Except-Else-Finally 行为
【发布时间】:2012-06-25 05:19:02
【问题描述】:

这是一些行为异常的代码。这是我编写的行为的简化版本。这仍然会证明奇怪的行为,我对为什么会发生这种情况有一些具体的问题。

我在 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
  • 为什么演示 1 返回 3 而不是 1?
  • 为什么演示 2 打印 6 而不是打印 6 w/4 或 5?

【问题讨论】:

    标签: python try-except


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      Python docs 状态:

      当在 try...finally 语句的 try 套件中执行 return、break 或 continue 语句时,finally 子句也会在“退出时”执行。

      函数的返回值由最后执行的 return 语句决定。由于 finally 子句总是执行,因此在 finally 子句中执行的 return 语句将始终是最后执行的:

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

      【讨论】:

      • 为什么第二个例子中的 5 不打印?我认为这仍然没有得到很好的解释。返回的答案很好,但为什么第二个示例中的 5 不打印
      • 哦,我想我在最初的尝试中发现了返回导致它最终立即跳到外部
      • 没错,因为finally 阻止始终运行。
      • 在demo 2中,为什么它执行了finally嵌套,最后踢到外面然后又回到嵌套finally完成return,而不是最终从外面简单地返回None?
      • 因为在调用return 语句时,Python 会检查任何需要执行的打开的finally 子句(参见上面的引用)。
      【解决方案3】:

      执行顺序为:

      1. try 块全部正常完成 -> finally 块 -> 函数结束
      2. 尝试块运行并进入异常 A -> finally 块 -> 函数结束
      3. try 块生成返回值并调用 return -> finally 块 -> 弹出返回值 -> 函数结束

      所以,finally 块中的任何返回都会提前结束这些步骤。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多