27

次の動作が少なくとも奇妙であることがわかりました。

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

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

returnの中で使用すると、例外は消えます。finallyそれはバグですか?それはどこかに文書化されていますか?

しかし、本当の質問 (および私が正しいとマークする答え) は次のとおり
です。その奇妙な動作を許可する Python 開発者の理由は何ですか?

4

4 に答える 4

54

returnの中で使用すると、例外は消えます。finally.. それはどこかに文書化されていますか?

それは:

finally が存在する場合は、「クリーンアップ」ハンドラーを指定します。try 句が実行されます。これには、except 句と else 句が含まれます。いずれかの句で例外が発生し、処理されない場合、例外は一時的に保存されます。finally 節が実行されます。保存された例外がある場合は、finally 句の最後で再発生します。finally 句で別の例外が発生したり、return または break ステートメントが実行されたりすると、保存された例外は失われます。

于 2009-02-05T18:03:39.233 に答える
36

あなたは Python 開発者の理由について尋ねました。私は彼らのために話すことはできませんが、他の行動は意味がありません. 関数は値を返すか、例外を発生させることができます。両方を行うことはできません。"finally" 句の目的は、例外に関係なく実行されることが "保証されている" クリーンアップ コードを提供することです。return ステートメントを finally 句に入れることで、例外に関係なく、何があっても値を返すことを宣言したことになります。Python が要求どおりに動作して例外を発生させた場合、"finally" 句の契約を破ることになります (返すように指示した値を返すことができないため)。

于 2009-02-08T16:15:35.020 に答える
4

これがfinallyブロックでのreturnの興味深い比較です-Java/C#/ Python / JavaScript :(アーカイブリンク

最後から戻る

ちょうど今日、私は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、それで私は1つが返されると思います。ただし、そうではありません。

2回目のリターンが実行されます

ロジックは理解できたので、最後にセクションを実行する必要がありますが、どういうわけか不安を感じます。この場合、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());  
 }  
}  

エラーCS0157制御はfinally節の本体を離れることができません

私はむしろこの振る舞いを好みます。finally節で制御フローを台無しにすることはできないので、足を撃たれるのを防ぎます。完全を期すために、他の言語が何をするかを確認しましょう。

Python:

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

Pythonも2を返します

JavaScript:

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

JavaScriptも2を返します

C ++とPHPにはfinally句がないため、コンパイラー/インタープリターを使用している最後の2つの言語を試すことはできません。

私たちの小さな実験は、C#がこの問題に対して最も優れたアプローチを持っていることをうまく示しましたが、他のすべての言語が同じ方法で問題を処理することを知って非常に驚きました。

于 2009-02-05T22:52:30.307 に答える
2

finally から戻るのは得策ではありません。私は、C#がこれを行うことを特に禁止していることを知っています。

于 2009-02-05T18:03:11.060 に答える