Python | 文法の基本:finally

Python
スポンサーリンク

finally の概要(成功・失敗に関わらず必ず実行される後始末)

finally は、try/except と組み合わせて使い、「例外が起きても起きなくても、最後に必ず実行したい処理」を書くためのブロックです。ファイルを閉じる、接続を切る、ロックを解放する、ログを確実に残すなど、後始末の場所として機能します。プログラムの安定性と信頼性を高めるための“安全装置”です。


基本構文と動作の流れ(ここが重要)

try / except / finally の役割分担

try には「失敗しうる最小限の処理」、except には「失敗時の対処」、finally には「必ず行う後始末」を書きます。finally は、try が成功した場合も、except でエラーを処理した場合も、さらには関数 return や break があっても“必ず”実行されます。

f = None
try:
    f = open("data.txt", "r", encoding="utf-8")  # 失敗しうる
    text = f.read()
    print(text)
except FileNotFoundError:
    print("ファイルが見つかりません")
finally:
    if f:
        f.close()  # 成否に関わらず必ず閉じる
Python

else と組み合わせて構造を明確にする

成功時だけ進めたい本処理は else に、後始末は finally に分けると意図が読みやすくなります。try は「失敗しうる最小範囲」に絞るのがコツです。

try:
    value = int(input("数量: ").strip())
except ValueError:
    print("整数で入力してください")
else:
    print(f"{value} 個を引き当てます")
finally:
    print("入力処理を終了します(ここは必ず実行)")
Python

例題で身につける(定番の後始末パターン)

例題1:ログファイルの確実なクローズ

log = None
try:
    log = open("app.log", "a", encoding="utf-8")
    log.write("起動しました\n")
    # 本処理...
except OSError as e:
    print(f"ログ書き込み失敗: {e}")
finally:
    if log:
        log.close()
Python

例題2:ネットワーク接続のクリーンアップ

conn = None
try:
    conn = connect_server()  # 仮の関数
    send(conn, "PING")
    recv(conn)
except TimeoutError:
    print("タイムアウトしました")
finally:
    if conn:
        disconnect(conn)  # 接続を必ず切る
Python

例題3:再試行と最後の通知

attempts = 0
success = False
try:
    while attempts < 3 and not success:
        attempts += 1
        success = do_task()  # 仮の処理
except RuntimeError as e:
    print("致命的な失敗:", e)
finally:
    print(f"試行回数: {attempts} / 成功: {success}")
Python

深掘りポイント(保証される実行・return と例外の相互作用)

return の前でも finally は実行される

関数内で try の途中に return があっても、実行を抜ける“直前”に finally が走ります。後始末が漏れないための強い保証です。

def read_first_line(path):
    f = None
    try:
        f = open(path, "r", encoding="utf-8")
        return f.readline()  # ここで戻る前に…
    except OSError:
        return None
    finally:
        if f:
            f.close()  # 必ず実行される
Python

例外が再送出されても finally は実行される

except で捕まえずに例外が外へ伝播する場合でも、finally は走ります。致命的エラー時の後始末が保証されます。

try:
    risky()
finally:
    cleanup()  # risky() が失敗しても必ず後始末
Python

finally 内の例外は“上書き”になるので注意

finally の中で新たな例外を発生させると、元の例外情報が失われます。後始末で失敗しうる処理は、さらに try/except で保護するのが安全です。

try:
    run()
finally:
    try:
        cleanup()  # 失敗しうるなら守る
    except Exception as e:
        print("後始末で失敗:", e)
Python

実務での設計指針(重要ポイントを丁寧に)

後始末は「finally」か「コンテキストマネージャ」

with 文は、入出と後始末を自動化できる「コンテキストマネージャ」の糖衣構文です。使える場面では with の方が簡潔で安全です。使えない場面や独自の複合後始末が必要なときに finally を選びます。

# with を使えるならこちらが簡潔で安全
with open("data.txt", "r", encoding="utf-8") as f:
    print(f.read())
# f.close() は自動で呼ばれる
Python

try は「失敗しうる最小範囲」に絞る

広く囲いすぎると原因特定が難しくなります。後始末は finally に、成功前提の処理は else に分離して構造化します。

後始末は“失敗しにくい形”に

  • 参照が None かを確認してから close/disconnect を呼ぶ。
  • 後始末自体も例外安全に(小さな try/except を挟む)。
  • ログは失敗してもプログラム全体を止めない運用に。

まとめ

finally は「成功・失敗に関わらず必ず実行される後始末」を書くための場所です。return の前でも、例外が外へ伝播するときでも実行されるため、リソース解放やクリーンアップの信頼性を担保できます。try を最小範囲に、成功時は else、後始末は finally に分離して読みやすく。with が使える場面はコンテキストマネージャで自動化し、それ以外は finally で確実に締める。この型を身につければ、初心者でも堅牢で落ち着きのある例外処理を書けるようになります。

タイトルとURLをコピーしました