Skip to content

3.1 例外処理

Pythonのプログラム実行中に例外(エラー)が発生すると、例外オブジェクトが作成され、例外の情報と発生箇所(Traceback)が出力されて処理が停止します。プログラムが強制終了されるのを防ぐためには、例外の発生が想定される箇所であらかじめ適切に例外処理を行うことが重要です。

本記事では、Pythonでより堅牢なプログラムを書くための例外処理について解説します。

例外が発生する可能性のある箇所は try-except で囲むことで、プログラムの停止を防ぐことができます。

1.1 基本的な try-except と複数の例外捕捉

Section titled “1.1 基本的な try-except と複数の例外捕捉”

except キーワードの後ろには、捕捉したい例外クラス(例:ZeroDivisionError)を指定します。もし指定した例外と一致しない例外が発生した場合、その例外は外側に再送出され、最終的にどこでも捕捉されなかった場合はプログラムが停止します。

発生した例外に応じて処理を分けたい場合は、複数の except 節を用いることができます。また、丸括弧で囲んだタプルを使用することで、1つの except 節で複数の例外クラスを指定することも可能です。

1.2 例外オブジェクトの取得 (as キーワード)

Section titled “1.2 例外オブジェクトの取得 (as キーワード)”

except 例外クラス as 変数名: の形式を使用すると、例外オブジェクトを受け取ることができ、except 節の中でエラー内容を出力するなどの用途に利用できます。

  • else: try 節の中で例外が一切送出されなかったときにのみ実行される処理を記述します。すべての except 節よりも後ろに置く必要があります。
  • finally: 例外の発生有無にかかわらず、必ず実行される処理(開いたファイルのクローズ処理など)を記述します。

【構文のルールまとめ】

  • exceptelsefinally はオプションですが、try 節のあとには except 節か finally 節のどちらかを置く必要があります。
  • 配置順序は try -> except -> else -> finally の順にする必要があります。

2.1 基底クラスで例外を捕捉する

Section titled “2.1 基底クラスで例外を捕捉する”

Pythonの例外クラスは継承階層を構成しています。すべての例外の親である BaseException クラスの下に、Exception クラスなどがあります。except 節に基底クラス(例えば ArithmeticError)を指定すると、その子・孫クラス(ZeroDivisionError など)の例外もまとめて捕捉できます。

2.2 独自の例外を定義・送出する

Section titled “2.2 独自の例外を定義・送出する”

Exception クラスを継承することで、新しい独自の例外クラスを定義できます。通常は Error で終わる名前で定義します。 プログラム内で意図的に例外を発生させるには raise 文を使用します。

複数の例外を送出するようなモジュールを作成する際は、そのモジュール専用の基底例外クラスを作成し、そこから派生させて各種エラー用の例外を定義するのが一般的です。独自の例外クラスには必要な属性だけを定義し、エラーに関する情報を取り出せる程度にとどめるのが良い使い方です。

3.1 複数の例外をグループ化する (ExceptionGroupexcept*)

Section titled “3.1 複数の例外をグループ化する (ExceptionGroup と except*)”

並行処理などで複数の無関係な例外が同時に発生する場合、それらをグループ化して扱うための ExceptionGroup クラスがあります。第1引数にはメッセージ文字列を、第2引数には例外のシーケンスを指定します。

ExceptionGroup は通常の except 節でも捕捉できますが、グループ全体を受け取るため、中に含まれる個々の例外を種類別に処理することはできません。含まれる特定の種類の例外だけを種類ごとに処理したい場合は except* 構文を使用します。なお、同じ try 文の中で except* 構文と通常の except 構文は併用できません。

3.2 例外にノートを追加する (add_note())

Section titled “3.2 例外にノートを追加する (add_note())”

add_note() メソッドを使用すると、例外にノート(注釈)を追加できます。例外が発生した際のエラー原因や詳細な状況などを追加することで、追加されたノートがトレースバックに表示されるようになり、デバッグやエラー追跡が容易になります。

4. よくあるエラーと適切な対処法

Section titled “4. よくあるエラーと適切な対処法”

例外処理を実装する際は、以下の点に注意してください。

  • try 節で囲む範囲は狭くする: 範囲が広すぎると、try 節が何を意図しているのか理解するのが困難になり、可読性が下がります。
  • すべての例外をまとめて捕捉しない: except Exception: のようにエラーの種類を特定せずに広範囲を捕捉してしまうと、プログラムの挙動が意図せず継続する可能性があります。また、例外の種類を全く指定しない except: 構文は、SystemExitKeyboardInterrupt(Ctrl+C入力など)といった例外まで握りつぶしてしまう恐れがあります。
  • 想定される例外を個別に捕捉する: FileNotFoundErrorZeroDivisionError など、発生が想定される例外をそれぞれ明示的に捕捉し、適切なエラーメッセージを出力するように修正すべきです。