回答:
早く帰ったら違いが出ます:
try:
run_code1()
except TypeError:
run_code2()
return None # The finally block is run before the method returns
finally:
other_code()
これと比較:
try:
run_code1()
except TypeError:
run_code2()
return None
other_code() # This doesn't get run if there's an exception.
違いを引き起こす可能性があるその他の状況:
run_code1()
、それがでない場合TypeError
。continue
and break
ステートメントなどの他の制御フローステートメント。を使用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 code is run no matter what else happens
...無限ループがない限り。またはパワーカット。またはos._exit()
。または...
os._exit
。
上記の他の回答に追加すると、例外は発生しなかった場合にのみ句が実行さ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.")
出力:
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.")
出力:
Could not write to file.
File closed.
finally
例外に関係なく句が実行されることがわかります。お役に立てれば。
else
。知っておくと便利です。
コードブロックは同等ではありません。このfinally
句は、run_code1()
以外の例外をスローした場合TypeError
、またはrun_code2()
例外をスローしたother_code()
場合にも実行されますが、最初のバージョンではこれらの場合は実行されません。
ドキュメントで説明されているように、このfinally
句は、あらゆる状況で実行する必要があるクリーンアップアクションを定義することを目的としています。
存在する場合
finally
は、「クリーンアップ」ハンドラを指定します。try
句は、いずれかを含む、実行されるexcept
とelse
句。いずれかの句で例外が発生して処理されない場合、例外は一時的に保存されます。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
句はどのイベントでも実行されます。TypeError
2つの文字列を分割することにより上昇はによって処理されていないexcept
後句したがって再上昇finally
句が実行されました。
実際のアプリケーションでは、finally節は、リソースの使用が成功したかどうかに関係なく、外部リソース(ファイルやネットワーク接続など)を解放するのに役立ちます。
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()
上記のコードは、コードの最初のブロックと同じ効果がありますが、より簡潔です。
Delphiを数年間専門的に使用することで、最終的に使用するクリーンアップルーチンを保護するように教えられました。Delphiは、メモリリークが発生しないように、tryブロックの前に作成されたリソースをクリーンアップするために、finallyの使用をほぼ強制します。これは、Java、Python、Rubyの動作方法でもあります。
resource = create_resource
try:
use resource
finally:
resource.cleanup
そして、リソースは試行してから最終的に何をするかに関係なくクリーンアップされます。また、実行がtry
ブロックに到達しない場合は、クリーンアップされません。(つまり、create_resource
それ自体が例外をスローします)コードを「例外的に安全」にします。
実際にfinallyブロックが必要な理由については、すべての言語で必要なわけではありません。例外がスタックをアンロールするときにクリーンアップを強制するデストラクターを自動的に呼び出したC ++。これは、最終的に言語を試してみるよりも、よりクリーンなコードの方向へのステップアップだと思います。
{
type object1;
smart_pointer<type> object1(new type());
} // destructors are automagically called here in LIFO order so no finally required.
tryブロックには、必須の句が1つだけあります。それは、tryステートメントです。except、else、finally句はオプションであり、ユーザー設定に基づきます。
finally:Pythonがtryステートメントを終了する前に、プログラムを終了する場合でも、あらゆる条件下でfinallyブロックのコードを実行します。たとえば、exceptまたはelseブロックでコードを実行中にPythonがエラーに遭遇した場合、プログラムを停止する前に、finallyブロックが引き続き実行されます。
これらのPython3コードを実行して、finallyの必要性を監視します。
ケース1:
count = 0
while True:
count += 1
if count > 3:
break
else:
try:
x = int(input("Enter your lock number here: "))
if x == 586:
print("Your lock has unlocked :)")
break
else:
print("Try again!!")
continue
except:
print("Invalid entry!!")
finally:
print("Your Attempts: {}".format(count))
ケース2:
count = 0
while True:
count += 1
if count > 3:
break
else:
try:
x = int(input("Enter your lock number here: "))
if x == 586:
print("Your lock has unlocked :)")
break
else:
print("Try again!!")
continue
except:
print("Invalid entry!!")
print("Your Attempts: {}".format(count))
毎回次の入力を試してください。
** Pythonの学習のごく初期の段階。
Excelシートを読みたいコードを実行しようとしました。sayという名前のシートがないファイルがある場合、問題は次のとおりでした:SheetSumエラーの場所に移動できません!! 私が書いたコードは:
def read_file(data_file):
# data_file = '\rr\ex.xlsx'
sheets = {}
try:
print("Reading file: "+data_file)
sheets['df_1'] = pd.read_excel(open(data_file,'rb'), 'SheetSum')
except Exception as excpt:
print("Exception occurred", exc_info=True)
return sheets
read_file(file)
shutil.move( file, dirpath +'\\processed_files')
エラーを与える:
[WinError 32]別のプロセスによって使用されているため、プロセスはファイルにアクセスできません
私は完全なtry except with finally
ブロックを追加finally
し、次のような場合にはファイルを閉じる必要があることを伝える必要がありました。
def read_file(data_file):
# data_file = '\rr\ex.xlsx'
sheets = {}
try:
print("Reading file: "+data_file)
sheets_file = open(data_file,'rb')
sheets['df_1'] = pd.read_excel(sheets_file, 'SheetSum')
except Exception as excpt:
print("Exception occurred", exc_info=True)
finally:
sheets_file.close()
return sheets
read_file(file)
shutil.move( file, dirpath +'\\processed_files')
それ以外の場合、ファイルはまだ開いたままで、背景です。
存在する場合
finally
は、クリーンアップハンドラーを指定します。try
句は、いずれかを含む、実行されるexcept
とelse
句。いずれかの句で例外が発生して処理されない場合、 例外は一時的に保存されます。finally
節が実行されます。保存された例外がある場合、それはfinally
条項の終わりに再度発生します。場合finally
句は別の例外を発生させ、保存された例外は新しい例外のコンテキストとして設定されています。
..もっとここに