Python finallyの使い方

この記事のポイント

Pythonのfinally(ファイナリー)は、エラーが発生してもしなくても、必ず実行したい処理を記述できる仕組みです。

この記事を読むと、次のようなことが身に付きます。

  • finallyがどのような場面で実行されるかがわかる
  • ファイルや接続のクリーンアップを確実に行う方法がわかる
  • try-exceptと組み合わせた安全なエラー処理の書き方がわかる

finallyの正しい使い方をマスターすれば、処理の成功や失敗に関わらず、必ず実行したい処理が行える信頼性の高いプログラムが書けるようになります。

目次

finallyとは?

finallyとは、try文と組み合わせて使う、例外処理の仕組みの一つです。

日常生活で例えると、「お店に入る(try)、買い物が成功する(正常時)、または欲しいものがなくて買えない(エラー時)、どちらの場合でも、お店からは必ず出る(finally)」という流れに似ています。

Pythonのfinallyブロックも同じように、プログラムの実行中にエラーが発生してもしなくても、必ず実行される処理を記述するために使われます。

例えば、ファイルを開いたり、データベースに接続したりした後、処理が成功しても失敗しても、必ず「ファイルを閉じる」「接続を切断する」といったリソース解放処理を行わせたい場合に役立ちます。

finallyの特徴

  • tryブロックの処理が成功した場合でも必ず実行される
  • exceptブロックで例外が処理された場合でも必ず実行される
  • tryブロックやexceptブロックの中でreturn文が実行されても、その直前に実行される
  • ファイル処理や接続などのリソース管理を忘れずに行うために使われる
  • より安全性の高いプログラムを作成できる

【関連】
Pythonをもっと詳しく学ぶならpaizaラーニング

基本構文

finally節は、try文の後に置いて使います。 exceptでエラーを処理する場合もしない場合も、finallyを最後に書いておくことで、どんな状況でも必ず実行させたい処理を定義できます。

まずは、エラーが発生しない(正常に処理が完了する)場合の基本的な形を見てみましょう。tryブロックの処理がすべて成功した後、finallyブロックが実行されます。

try: print("処理を開始します") result = 10 / 2 print(f"計算結果: {result}") finally: print("処理を終了します")

出力結果

処理を開始します
計算結果: 5.0
処理を終了します

この例では、tryブロック内の処理(10 / 2)が正常に成功しているため、「処理を開始します」「計算結果: 5.0」が順に表示されます。その後、finallyブロックが実行され、「処理を終了します」と表示されています。

次に、エラーが発生した場合のパターンです。tryブロックでエラーが起きると、exceptブロックが実行され、その後にfinallyブロックが実行されます。

try: print("エラーが発生する処理") result = 10 / 0 except ZeroDivisionError: print("ゼロ除算エラーを検知しました") finally: print("finally節は必ず実行されます")

出力結果

エラーが発生する処理
ゼロ除算エラーを検知しました
finally節は必ず実行されます

この例では、tryブロック内で10 / 0というゼロ除算エラーが発生しています。そのため、処理が中断してexcept ZeroDivisionError:のブロックが実行され、「ゼロ除算エラーを検知しました」と表示されます。

実用例

ここからは、実際の開発現場でもよく使われる、finallyの活用例をいくつか紹介します。 ファイル操作やデータベース接続など、リソース解放処理が重要な場面でfinallyがどのように役立つのかを見ていきましょう。各サンプルコードには動物に関するデータを使用し、親しみやすい形で解説していきます。それぞれのコード例は実行可能な形で記載しているため、実際に手元で動かして動作を確認することができます。

ファイルを確実に閉じる処理

open関数でファイルを開いた後、処理中にエラーが発生すると、closeメソッドが実行されずにファイルが開きっぱなしになる可能性があります。 finallyブロックでclose処理を行うことで、エラーが起きても必ずファイルを閉じることができます。

file = None try: file = open("animal.txt", "w", encoding="utf-8") file.write("イヌ\n") # 意図的にエラーを発生させる result = 10 / 0 # 以下の処理はエラーのため実行されない file.write("ネコ\n") print("ファイル書き込み完了") except ZeroDivisionError: print("エラーが発生しました: ゼロ除算エラー") finally: if file: file.close() print("ファイルを閉じました(エラー発生時も実行)")

出力結果

エラーが発生しました: ゼロ除算エラー
ファイルを閉じました(エラー発生時も実行)

この例では、tryブロックでanimal.txtを開き、「イヌ」を書き込んだ直後にゼロ除算エラーが発生しています。そのため、後続のwrite処理やprint文は実行されず、処理がexceptブロックに移って「エラーが発生しました」と表示されます。

重要なのはエラーで処理が中断した後でも、finallyブロックが必ず実行されている点です。finallyにfile.closeを記述することでファイルが開きっぱなしになるのを防いでいます。

データベース接続の安全な切断

データベースに動物情報を登録する際、接続を確実に切断します。エラーが起きても接続は解放されるため、コネクションプールの枯渇を防げます。

connection = None try: connection = "DB接続確立" print(f"{connection}: 動物テーブルにアクセス") print("ウサギのデータを登録") finally: if connection: print("データベース接続を切断しました")

出力結果

DB接続確立: 動物テーブルにアクセス
ウサギのデータを登録
データベース接続を切断しました

この例では、tryブロックでデータベース接続とデータ登録を模した処理を実行しています。処理が正常に終わると、finallyブロックが実行され、if connection:で接続があることを確認してから「データベース接続を切断しました」と表示し、後片付けを行っています。

ネットワーク通信後のクリーンアップ

外部のAPIに接続してデータをやり取りするネットワーク通信でも、finallyは役立ちます。 以下のコードは、APIから動物の画像を取得する処理を模しています。通信処理が終わった後、finallyで必ず接続を閉じるようにしています。

connection = None try: connection = "API接続" print(f"{connection}を開始") print("パンダの画像を取得中") animal_data = "パンダ画像データ" print(f"取得完了: {animal_data}") finally: if connection: print("ネットワーク接続をクローズしました")

出力結果

API接続を開始
パンダの画像を取得中
取得完了: パンダ画像データ
ネットワーク接続をクローズしました

この例では、tryブロックでAPIへの接続と画像データの取得を模した処理を行っています。処理が完了すると、finallyブロックが実行され、if connection:で接続が確立されていたことを確認した後、「ネットワーク接続をクローズしました」と表示して、接続を解放しています。

一時ファイルの削除処理

処理の途中で一時的にファイルを作成し、処理が終わったら必ず削除したい場合があります。 以下のコードでは、with文で一時ファイルへの書き込みを行い、finallyブロックでその一時ファイルを削除しています。

temp_file = "temp_animal.txt" try: print(f"一時ファイル {temp_file} を作成") with open(temp_file, "w") as f: f.write("キリン") print("一時ファイルに書き込み完了") finally: print(f"{temp_file} を削除しました")

出力結果

一時ファイル temp_animal.txt を作成
一時ファイルに書き込み完了
temp_animal.txt を削除しました

この例では、tryブロック内でwith open(...)を使い、一時ファイルを作成して書き込みを行っています。withブロックを抜けるとファイルは自動で閉じられます。

その後、finallyブロックが実行され、作成した一時ファイル(temp_animal.txt)を削除を模した処理を実行しています。with文は自動でファイルを閉じてくれますが、ファイルの削除は自動では行われないため、finallyが役立ちます。

ログ記録を確実に行う方法

動物情報の処理ログを記録します。処理が成功しても失敗しても、ログは必ず出力されるため、トラブルシューティングに役立ちます。

try: print("動物データ処理を開始") animals = ["ライオン", "トラ", "ヒョウ"] for animal in animals: print(f"{animal}を処理中") finally: print("ログ: 処理終了時刻を記録しました")

出力結果

動物データ処理を開始
ライオンを処理中
トラを処理中
ヒョウを処理中
ログ: 処理終了時刻を記録しました

この例では、tryブロックで動物データのリストを順番に処理しています。for文の繰り返し処理がすべて完了した後、finallyブロックが実行され、「ログ: 処理終了時刻を記録しました」と表示されます。もしforループの途中でエラーが発生したとしても、finallyのログ記録は実行されます。

リソースカウンターの管理

動物データベースへの同時アクセス数を管理します。処理完了後は必ずカウンターをデクリメントし、正確な接続数を維持します。

システムへの同時アクセス数など、リソースの数を管理する際にもfinallyが役立ちます。 処理を開始する前にカウンターをインクリメント、処理が終わった後に必ずカウンターデクリメントすることで、正確な数を保てます。

active_connections = 0 try: active_connections += 1 print(f"接続数: {active_connections}") print("ゾウのデータを検索中") finally: active_connections -= 1 print(f"接続解放後の接続数: {active_connections}")

出力結果

接続数: 1
ゾウのデータを検索中
接続解放後の接続数: 0

この例では、tryブロックが実行されるとactive_connectionsをインクリメントし、現在の接続数を表示しています。その後、データ検索を模した処理を実行しています。処理が終わると、finallyブロックが実行され、active_connectionsをデクリメント、接続が解放された後の数値を表示しています。

処理時間の計測と記録

ある処理にかかった時間を計測する場合、処理が成功してもエラーで中断しても、かかった時間は記録したいものです。 tryブロックの直前に開始時刻を記録し、finallyブロックで終了時刻との差を計算して表示します。

import time start_time = time.time() try: print("サルの画像を変換開始") time.sleep(0.1) print("変換処理完了") finally: elapsed = time.time() - start_time print(f"処理時間: {elapsed:.3f}秒")

出力結果

サルの画像を変換開始
変換処理完了
処理時間: 0.100秒

この例では、tryブロックの前にtime.time()で開始時刻をstart_timeに保存しています。tryブロック内で画像変換を模した処理time.sleepを実行した後、finallyブロックが実行されます。finallyブロック内で現在の時刻からstart_timeを引くことで、処理時間を計算して表示しています。

まとめ

Pythonのfinallyは、例外処理で欠かせない重要な構文です。エラーが起きても起きなくても必ず実行される特性を活かすことで、安全なリソース管理を確実に行えます。この記事では、基本的な使い方からエラー発生時の動作まで解説しました。

finallyが活躍する場面

  • ファイルや接続を使い終わったら必ず閉じたいとき
  • 処理の成功・失敗に関わらずログを残したいとき
  • 処理後に一時ファイルやデータを必ず削除したいとき

finallyを用いる上で、押さえておきたいポイントを覚えておきましょう。

重要なポイント

  • tryブロックの処理が成功しても失敗しても実行される
  • exceptブロックでエラーを処理した後にも実行される
  • return文で関数を抜ける直前にも実行される

finallyを適切に活用することで、プログラムの信頼性が大きく向上します。特にファイル操作やネットワーク通信などでは必須の技術といえます。

初めてPythonを学ぶ方も、この記事で紹介したfinallyを実際に書いて、基本的な使い方を試してみてください。

finallyによる安全なリソース管理は、実際の開発でよく使用されます。マスターしておけば役立つこと間違いなしです。

ぜひfinallyをマスターして、より安全で実用的なプログラムを作成できるようになりましょう。

レベルを更に上げたい方はpaizaプログラミングスキルチェックへ

  1. paizaラーニングトップ
  2. リファレンス
  3. Pythonのリファレンス記事一覧
  4. Python finallyの使い方