2025年5月21日水曜日

Pythonにおけるexceptとは

 Pythonにおけるexceptは、**例外処理(エラーハンドリング)**を行うためのキーワードです。プログラムの実行中に予期せぬエラー(例外)が発生した場合に、プログラムがクラッシュするのを防ぎ、適切に処理を継続させるために使われます。


try-exceptブロックの基本

exceptは常にtryブロックとセットで使われます。基本的な構文は以下の通りです。

Python
try:
    # エラーが発生する可能性のあるコード
    # このブロック内のコードが実行されます
except 例外の種類:
    # 例外が発生した場合に実行されるコード
    # 例外を捕捉して処理します

どう機能するか:

  1. tryブロック: まず、tryブロック内のコードが実行されます。
  2. エラーが発生しない場合: tryブロック内のコードが問題なく実行されれば、exceptブロックはスキップされ、try-exceptブロックの後のコードが実行されます。
  3. エラーが発生した場合: tryブロック内で指定した例外の種類に該当するエラーが発生すると、tryブロックの残りのコードは実行されず、すぐに該当するexceptブロックに処理が移り、その中のコードが実行されます。

exceptの様々な使い方

1. 特定の例外を捕捉する

最も一般的な使い方です。どの種類のエラーが発生したときに、どの処理を行うかを明示します。

Python
try:
    num = int("abc") # ValueError が発生する
except ValueError:
    print("数値に変換できない値を入力しました。")

この例では、"abc"int()で整数に変換しようとするため、ValueErrorが発生します。except ValueError:がそのエラーを捕捉し、「数値に変換できない値を入力しました。」と表示します。


2. 複数の例外を捕捉する

複数の異なる例外に対して、同じ処理を行う場合や、それぞれ異なる処理を行う場合があります。

a) 複数の例外をまとめて捕捉 (同じ処理)

複数の例外をタプルで指定すると、それらのいずれかの例外が発生した場合に同じexceptブロックが実行されます。

Python
try:
    # 例1: 除算エラー
    # result = 10 / 0

    # 例2: 存在しないファイルを開くエラー
    with open("non_existent_file.txt", "r") as f:
        content = f.read()

except (ZeroDivisionError, FileNotFoundError):
    print("エラーが発生しました。除算エラーかファイルが見つかりません。")


b) 複数の例外を個別に捕捉 (異なる処理)

それぞれの例外に対して異なる処理を行いたい場合は、複数のexceptブロックを連ねて記述します。

Python
try:
    num1 = int(input("数値を入力してください: "))
    num2 = int(input("もう一つ数値を入力してください: "))
    result = num1 / num2
    print(f"結果: {result}")
except ValueError:
    print("有効な数値を入力してください。")
except ZeroDivisionError:
    print("0で割ることはできません。")
except Exception as e: # その他の予期せぬエラーを捕捉
    print(f"予期せぬエラーが発生しました: {e}")

この例では、ユーザーの入力に応じて以下のように動作します。

  • 文字列が入力された場合: ValueError
  • 2番目の数値に0が入力された場合: ZeroDivisionError

3. すべての例外を捕捉する (Exceptionクラス)

特定の例外を想定できない場合や、単にプログラムがクラッシュするのを防ぎたい場合は、最も基本的な例外クラスであるExceptionを捕捉します。

Python
try:
    # どんなエラーが起こるかわからないコード
    value = [1, 2, 3][5] # IndexError が発生する
except Exception as e:
    print(f"何らかのエラーが発生しました: {e}")

as eとすることで、発生した例外オブジェクトをeという変数に格納し、その詳細情報を表示できます。これはデバッグに非常に役立ちます。

注意点: Exceptionですべてを捕捉すると、予期せぬエラーまで隠してしまう可能性があります。できるだけ具体的な例外を捕捉し、最後にExceptionでそれ以外のエラーを捕捉するのがベストプラクティスです。


4. 例外名を省略する(非推奨)

exceptの後に例外名を指定しないこともできますが、これは非推奨です。

Python
try:
    value = 10 / 0
except: # どんな例外でも捕捉する
    print("エラーが発生しました。")

この方法は、システム終了などの非常に深刻なエラーまで捕捉してしまうため、意図しない挙動につながることがあります。基本的にはexcept Exceptionを使うか、具体的な例外を指定するべきです。


elseブロックとfinallyブロック

try-exceptブロックには、さらにelsefinallyというオプションのブロックを追加できます。


elseブロック

tryブロック内のコードがエラーなく正常に完了した場合にのみ実行されます。

Python
try:
    num = int("123")
except ValueError:
    print("数値に変換できませんでした。")
else:
    print(f"数値に変換され、正常に処理されました: {num}")

finallyブロック

tryブロックの成功・失敗、例外の発生有無にかかわらず、常に実行されるコードです。ファイルのクローズやリソースの解放など、必ず実行したいクリーンアップ処理に使われます。

Python
file = None
try:
    file = open("my_data.txt", "r")
    content = file.read()
    print("ファイルの内容:", content)
except FileNotFoundError:
    print("ファイルが見つかりません。")
finally:
    if file:
        file.close() # ファイルが開かれていれば必ず閉じる
        print("ファイルを閉じました。")

なぜ例外処理が必要なのか?

  • プログラムの堅牢性: 予期せぬ入力や環境の変化によってプログラムが停止するのを防ぎ、安定した動作を保証します。
  • ユーザーエクスペリエンスの向上: エラーメッセージをユーザーに分かりやすく表示し、何が問題だったのかを伝えたり、再試行を促したりできます。
  • デバッグの支援: Exception as eを使ってエラーの詳細情報を取得することで、問題の特定と修正が容易になります。
  • リソースの適切な管理: finallyを使って、ファイルやデータベース接続などのリソースを確実に解放し、リソースリークを防ぎます。

まとめ

exceptはPythonで堅牢なコードを書く上で不可欠な要素です。適切な例外処理を行うことで、プログラムはより安定し、ユーザーフレンドリーになります。

どの例外を捕捉すべきか、またelsefinallyをどう使うかは、プログラムの要件やエラーの種類によって使い分けることが重要です。

何か具体的なシナリオでexceptの使い方を知りたい場合は、お気軽にご質問ください!