2012-07-18 11 views
134

なぜfinallytry...except...finallyステートメントに必要かわかりません。私の意見では、このコードブロックPythonで「finally」節が必要なのはなぜですか?

try: 
    run_code1() 
except TypeError: 
    run_code2() 
other_code() 

finallyを使用して、この1と同じである:

try: 
    run_code1() 
except TypeError: 
    run_code2() 
finally: 
    other_code() 

私は何かが足りないのですか?

答えて

191

あなたが早く返す場合、それが違いを作る:例外が内側にスローされた場合

  • try: 
        run_code1() 
    except TypeError: 
        run_code2() 
        return None 
    
    other_code() # This doesn't get run if there's an exception. 
    
    違いを引き起こす可能性があります

    その他の状況:

    try: 
        run_code1() 
    except TypeError: 
        run_code2() 
        return None # The finally block is run before the method returns 
    finally: 
        other_code() 
    

    はこれに比較exceptブロック。

  • 例外がrun_code1()にスローされますが、それはTypeErrorではありません。
  • continueおよびbreakステートメントなどの他の制御フローステートメント。
+0

試し: #X =こんにちは+ 20 X = 10 + 20以外 :他に X = 20 + 30 '私はブロック以外でいます' 印刷: 印刷 X 'を私は他のブロックにしています' + = 1 finally: print '最後にx =%s'%(x) –

11

これらは同等ではありません。最後にコードは実行されても何も起こりません。これは、実行しなければならないクリーンアップコードに役立ちます。

+6

「最後にコードは実行されても実行されます」...無限ループがない限り。またはpowercut。または 'os._exit()'。または... –

+2

... segfault。または 'SIGABRT'。 –

+2

@マーク実際には、sys.exitは通常の例外をスローします。しかし、はい、プロセスを即座に終了させるものは何も実行されないことを意味します。 – Antimony

7

コードブロックは同等ではありません。 run_code1()TypeError以外の例外をスローした場合、またはrun_code2()が例外をスローした場合はfinally句も実行されますが、最初のバージョンのother_code()は実行されません。

6

run_code1()TypeErrorではない例外を発生させる場合、最初の例ではどうなりますか? ... other_code()は実行されません。

finally:バージョンと比較してください:other_code()は、例外が発生しても実行されることが保証されています。

35

finallyを使用すると、例外が発生するかどうかに関係なく、ファイルまたはリソースが閉じられたり、解放されたりすることがありますが、例外をキャッチしなくてもになります。(それとも、その特定の例外をキャッチしない場合。)

myfile = open("test.txt", "w") 

try: 
    myfile.write("the Answer is: ") 
    myfile.write(42) # raises TypeError, which will be propagated to caller 
finally: 
    myfile.close()  # will be executed before TypeError is propagated 

をこの例では、with文を使用したほうが良いと思いますが、この種の構造は、他の種類のリソースのために使用することができます。

数年後、私はfinallyの乱用についてa blog postを書きましたが、読者は面白いかもしれません。

3

finallyは、"クリーンアップアクション"を定義します。 finally句は、例外(処理していなくても)が発生したかどうかに関わらず、tryステートメントを終了する前のどのイベントでも実行されます。

私はByersさんの例です。

2

最終的には、主な作業のコードを実行する前に「オプション」コードを実行したい場合や、オプションのコードがさまざまな理由で失敗する場合にも使用できます。

次の例では、store_some_debug_infoがどのような例外をスローする可能性があるかを正確にはわかりません。

我々は実行することができます:

try: 
    store_some_debug_info() 
except Exception: 
    pass 
do_something_really_important() 

をしかし、ほとんどのリンターは、例外のあまりに漠然とキャッチ文句を言うでしょう。また、エラーの場合はpassだけを選択しているため、exceptブロックは実際に価値を追加しません。

try: 
    store_some_debug_info() 
finally: 
    do_something_really_important()  

上記のコードは、第1ブロックのコードと同じ効果がありますが、より簡潔です。

1

完璧な例は以下の通りである:

try: 
    #x = Hello + 20 
    x = 10 + 20 
except: 
    print 'I am in except block' 
    x = 20 + 30 
else: 
    print 'I am in else block' 
    x += 1 
finally: 
    print 'Finally x = %s' %(x) 
1

としてはdocumentationで説明し、finally句がすべての状況下でを実行しなければならないクリーンアップ・アクションを定義することを意図しています。

finallyが存在する場合は、「クリーンアップ」ハンドラを指定します。 exceptおよびelse句を含むtry 句が実行されます。いずれかの句で 例外が発生し、処理されない場合は、 例外が一時的に保存されます。 finally句が実行されます。 保存された例外がある場合、finally 節の最後に再発生します。

例:

>>> def divide(x, y): 
...  try: 
...   result = x/y 
...  except ZeroDivisionError: 
...   print("division by zero!") 
...  else: 
...   print("result is", result) 
...  finally: 
...   print("executing finally clause") 
... 
>>> divide(2, 1) 
result is 2.0 
executing finally clause 
>>> divide(2, 0) 
division by zero! 
executing finally clause 
>>> divide("2", "1") 
executing finally clause 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 3, in divide 
TypeError: unsupported operand type(s) for /: 'str' and 'str' 

あなたが見ることができるように、finally句はいずれにしても実行されます。 2つの文字列を分割して生成したTypeErrorは、except句で処理されないため、finally句が実行された後に再生成されます。

実際のアプリケーションでは、finally節は、リソースの使用が成功したかどうかにかかわらず、外部リソース(ファイルやネットワーク接続など)を解放するのに便利です。

1

finally句は、何も関係なく実行されますが、else句は例外が発生しなかった場合にのみ実行されます。例外なくファイルへの書き込み例えば

、出力を次のようになります。

file = open('test.txt', 'w') 

try: 
    file.write("Testing.") 
    print("Writing to file.") 
except IOError: 
    print("Could not write to file.") 
else: 
    print("Write successful.") 
finally: 
    file.close() 
    print("File closed.") 

OUTPUT:

Writing to file. 
Write successful. 
File closed. 

例外がある場合、コードは次のように出力します(注意深いエラーは、ファイルを再作成することによって引き起こされることに注意してください広告のみ。

file = open('test.txt', 'r') 

try: 
    file.write("Testing.") 
    print("Writing to file.") 
except IOError: 
    print("Could not write to file.") 
else: 
    print("Write successful.") 
finally: 
    file.close() 
    print("File closed.") 

OUTPUT:

Could not write to file. 
File closed. 

我々はfinally句は関係なく、例外の実行ことがわかります。お役に立てれば。

関連する問題