我至少发现了以下行为 诡异的:

def errors():
    try:
        ErrorErrorError
    finally:
        return 10

print errors()
# prints: 10
# It should raise: NameError: name 'ErrorErrorError' is not defined

使用时异常消失 return 里面一个 finally 条款。这是一个错误吗?这有记录在任何地方吗?

但真正的问题(以及我将标记为正确的答案)是:
python 开发人员允许这种奇怪行为的原因是什么?

有帮助吗?

解决方案

您问了一下Python开发者的推理。我不能替他们说话,但没有其他行为很有道理。函数可以返回一个值,也可以引发异常;它不能两者都做。一个“终于”条款的目的是提供一种是“保证”来运行,无论异常清理代码。通过把一个return语句中finally语句,你已经声明要返回值,无论什么时候,无论异常。如果Python的表现为你所问及引发的异常,这将是打破了“终于”条款的合同(因为它会失败,返回你告诉它返回的值)。

其他提示

  

当您使用return一个finally子句中的异常消失。 ..是记载地方?

正是:

  

如果最后存在时,它指定一个“清除”处理程序。 try子句被执行,包括任何除了和其他条款。如果在任何条款发生异常,并没有被处理,除了被暂时保存。最终条款执行。如果有保存的例外,它是在最后条款的最终重新升起。 如果最终条款引发了另一个异常或执行了return或break语句,保存异常丢失。

以下是 Java/C#/Python/JavaScript 中finally 块中 return 的有趣比较:(存档链接)

从最后返回

就在今天,我正在帮助解决 Java 中的一些错误,并遇到了 有趣的问题 - 如果您在 try/catch 中使用 return,会发生什么 陈述?最后部分是否应该启动?我简化了 以下代码片段出现问题:

下面的代码打印出什么?

class ReturnFromFinally {  
 public static int a() {  
  try {  
   return 1;  
  }  
  catch (Exception e) {}  
  finally{  
   return 2;  
  }  
 }  

        public static void main(String[] args) {  
  System.out.println(a());  
        }  
}  

我最初的猜测是,它应该打印出来 1, ,我打电话 return, ,所以我假设,一个会被退回。但是,情况并非如此:

the second return is executed

我了解逻辑,最后必须执行部分,但是我对此感到不安。让我们看看 C# 在这种情况下做了什么:

class ReturnFromFinally  
{  
 public static int a()  
 {  
  try {  
          return 1;  
  }  
  catch (System.Exception e) {}  
  finally   
  {   
   return 2;  
  }  
 }  

 public static void Main(string[] args)  
 {  
  System.Console.WriteLine(a());  
 }  
}  

error CS0157 Control cannot leave the body of a finally clause

我更喜欢这种行为,最终子句中的控制流程无法混乱,因此它可以防止我们在脚上射击自己。只是为了完整,让我们检查其他语言的作用。

Python:

def a():  
 try:  
  return 1  
 finally:  
  return 2  
print a()  

Python returns 2 as well

JavaScript:

<script>  
function ReturnFromFinally()  
{  
 try  
 {  
  return 1;  
 }  
 catch (e)  
 {  
 }  
 finally  
 {  
  return 2;  
 }  
}  
</script>  
<a onclick="alert(ReturnFromFinally());">Click here</a>  

JavaScript returns 2 as well

C ++和PHP中没有最终子句,因此我无法尝试使用编译器/解释器的最后两种语言。

我们的小实验很好地表明,C#具有解决这个问题的最佳方法,但是我很惊讶地得知所有其他语言都以相同的方式处理该问题。

从最后返回是的一个好主意。我知道C#具体不允许对这样做。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top