[Pythonのはじめ方] Part16: 例外処理(try, except, finally)

はじめに:例外処理ってなに?

プログラムを書いていると、予期せぬエラーが発生することがあります。例えば、「0で割り算をしてしまった」「存在しないファイルを開こうとした」などです。これらのエラーは「例外 (Exception)」と呼ばれます。

例外が発生すると、通常、プログラムはその場で停止してしまいます。しかし、例外処理を適切に行うことで、プログラムが突然終了するのを防いだり、エラー発生時に特定の処理(例えばエラーメッセージを表示するなど)を実行させたりできます。プログラムをより頑丈(ロバスト)にするための重要な仕組みです。

基本的な使い方:tryexcept

Pythonの例外処理の基本は tryexcept ブロックを使います。

  • try ブロック:この中に、例外が発生する可能性のあるコードを書きます。
  • except ブロック:try ブロック内で特定の例外が発生した場合に、この中のコードが実行されます。

例:ゼロ除算エラーをキャッチする

数値を0で割ろうとすると ZeroDivisionError という例外が発生します。これを try-except で捕捉してみましょう。

try:
    num = 10 / 0  <span class="code-comment"># ここで ZeroDivisionError が発生する</span>
    print("計算結果:", num) <span class="code-comment"># この行は実行されない</span>
except ZeroDivisionError:
    print(" 0で割ることはできません!")

print("プログラムは継続しています...")

<span class="code-comment"># --- 実行結果 ---</span>
<span class="code-comment">#  0で割ることはできません!</span>
<span class="code-comment"># プログラムは継続しています...</span>

try ブロック内で ZeroDivisionError が発生したため、except ZeroDivisionError: ブロック内のコードが実行され、エラーメッセージが表示されました。重要なのは、プログラムが途中で停止せず、最後の print 文まで実行されている点です。

複数の例外をキャッチする

複数の種類の例外を処理したい場合は、except ブロックを複数書くことができます。

my_list = [1, 2, 3]
index_str = "a" <span class="code-comment"># わざと文字列にする</span>

try:
    index = int(index_str) <span class="code-comment"># ここで ValueError が発生する可能性</span>
    print("リストの要素:", my_list[index]) <span class="code-comment"># ここで IndexError が発生する可能性</span>
except ValueError:
    print(" 数値に変換できませんでした。")
except IndexError:
    print(" リストの範囲外のインデックスです。")
except Exception as e: <span class="code-comment"># その他の予期せぬエラーをキャッチ</span>
    print(f" その他のエラーが発生しました: {e}")

<span class="code-comment"># --- index_str が "a" の場合 ---</span>
<span class="code-comment">#  数値に変換できませんでした。</span>

<span class="code-comment"># --- index_str が "10" の場合 ---</span>
<span class="code-comment">#  リストの範囲外のインデックスです。</span>

発生した例外の種類に応じて、対応する except ブロックが実行されます。最後の except Exception as e: は、それまでの except でキャッチされなかった全ての例外を捕捉します。as e と書くことで、発生した例外オブジェクト(エラーの詳細情報)を変数 e で受け取ることができます。

注意: except: のように例外の種類を指定しない(または except Exception: を使う)と、すべての種類のエラーを捕捉してしまいます。これは意図しないエラーまで隠蔽してしまう可能性があるため、できるだけ具体的な例外を指定することが推奨されます。

エラーがなかった場合の処理:else ブロック

try ブロック内のコードが例外を発生させずに正常に完了した場合にのみ実行したい処理は、else ブロックに書くことができます。

try:
    num_str = input("数値を入力してください: ")
    num = int(num_str)
except ValueError:
    print(" 数値以外が入力されました。")
else:
    print(f" 入力された数値は {num} です。") <span class="code-comment"># 例外が発生しなかった場合のみ実行</span>

<span class="code-comment"># --- "123" と入力した場合 ---</span>
<span class="code-comment"># 数値を入力してください: 123</span>
<span class="code-comment">#  入力された数値は 123 です。</span>

<span class="code-comment"># --- "abc" と入力した場合 ---</span>
<span class="code-comment"># 数値を入力してください: abc</span>
<span class="code-comment">#  数値以外が入力されました。</span>

else ブロックは、try ブロックの直後に、except ブロックの後に記述します。例外が発生した場合は else ブロックは実行されません。

必ず実行される処理:finally ブロック

finally ブロックは、try ブロック内で例外が発生したかどうかに関わらず、最後に必ず実行される処理を記述します。

ファイルを開いた後に必ず閉じる、ネットワーク接続を切断するなど、後片付け処理によく使われます。

f = None <span class="code-comment"># 変数を初期化</span>
try:
    f = open("my_file.txt", "w", encoding="utf-8") <span class="code-comment"># ファイルを開く(書き込みモード)</span>
    content = input("ファイルに書き込む内容: ")
    num = int(content) <span class="code-comment"># わざと数値変換(エラーを起こす可能性)</span>
    f.write(str(num))
except ValueError:
    print(" 数値以外は書き込めません。")
except Exception as e:
    print(f" その他のエラー: {e}")
else:
    print(" ファイルに書き込みました。")
finally:
    if f: <span class="code-comment"># ファイルが正常に開かれていたら</span>
        f.close() <span class="code-comment"># 必ずファイルを閉じる</span>
        print(" ファイルを閉じました。")
    else:
        print(" ファイルは開かれませんでした。")

<span class="code-comment"># --- "123" と入力した場合 ---</span>
<span class="code-comment"># ファイルに書き込む内容: 123</span>
<span class="code-comment">#  ファイルに書き込みました。</span>
<span class="code-comment">#  ファイルを閉じました。</span>

<span class="code-comment"># --- "abc" と入力した場合 ---</span>
<span class="code-comment"># ファイルに書き込む内容: abc</span>
<span class="code-comment">#  数値以外は書き込めません。</span>
<span class="code-comment">#  ファイルを閉じました。</span>

この例では、数値変換で ValueError が発生しても、正常に書き込めても、finally ブロックは必ず実行され、ファイルが閉じられます(ファイルが開かれていれば)。

Tip: ファイル操作などでは、with 文を使うと finally で明示的に close() を書かなくても自動で後片付けをしてくれるため、より簡潔で安全なコードになります。(with 文は Step 3 で学びましたね!)

まとめ

今回はPythonの例外処理の基本である try, except, else, finally を学びました。

構文 役割
try: 例外が発生する可能性のあるコードを記述する場所。
except 例外の種類: 指定した種類の例外が try ブロックで発生した場合に実行される処理。
else: try ブロックで例外が発生しなかった場合に実行される処理。
finally: 例外の発生有無に関わらず、最後に必ず実行される処理(後片付けなど)。

例外処理を使いこなすことで、予期せぬエラーにも対応できる、より安定したプログラムを作成することができます。最初は少し難しく感じるかもしれませんが、実際にコードを書いて試してみるのが一番です!

参考情報

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です