Pythonの例外処理についてまとめました。
最初にPythonの例外処理について解説しています。
その後に下記について書いています。
・エラーが起きなかった時の処理を書く(else)
・処理の最後に必ず実行される処理を書く(finally)
載せているコードについては、Pythonの3.11.0バージョンを使って動作を確認しました。
公式ドキュメントではこちらにエラーと例外についての記載があります。
Pythonの例外処理とは?(try/except)
例外はプログラム実行時にエラーが発生することです。
例えば、下記のようなコードでは、0除算のエラーになります。
score = 100
result = score / 0
print (result)
score変数の値を0で割ろうとしているため、プログラム実行時にZeroDivisionErrorが発生します。
これに対して、例外処理を書いておくとプログラムの中でエラーが発生した場合に、エラー時に行いたい処理を定義することができます。
例外処理の対象にしたいコードは、tryブロックの配下に書きます。
例外が発生した場合にはexceptブロックの配下に処理が移行します。
先ほどのコードを下記のように修正しました。
try:
score = 100
result = score / 0
print (result)
except:
print("エラーが発生しました。")
エラーが発生する0除算のコードをtryブロックの配下に移しています。
こうすると、tryブロックの処理でエラーが発生すると、except配下の処理に移ります。
結果、「エラーが発生しました。」が出力されて処理が終わります。
例外クラスを指定する
例外クラスをexceptに指定することができます。
例外クラスを指定するには、下記のようにします。
try:
score = 100
result = score / 0
print (result)
except Exception as error:
print(type(error))
print(error)
print("エラーが発生しました。")
exceptにExceptionクラスを指定しました。
Exceptionクラスは、システム終了以外の例外の親クラスです。
error変数にはエラー情報が入ってきます。
0除算でエラーが発生すると、exceptに処理が移ります。
error変数の内容をtype関数で出力しています。
その後にerror変数自体をprint関数で出力しました。
出力結果を確認すると、下記のようになります。
<class 'ZeroDivisionError'>
division by zero
エラーが発生しました。
ZeroDivisionErrorクラスのオブジェクトが取得できていて、0除算エラーになっていることが確認できました。
複数の例外を指定する
例外クラスを複数指定して、それぞれの発生した例外で処理を振り分けることができます。
try:
score = 100
result = score / 0
print (result)
except ZeroDivisionError as error:
print('0除算エラーです。')
except Exception as error:
print("その他エラーが発生しました。")
先ほどのコードを少し修正して、例外を追加して、処理を振り分けてみました。
0除算が発生するので、exceptにZeroDivisionErrorクラスを書いている方に処理が移ります。
結果、「0除算エラーです。」だけが出力されて処理が終わります。
このように、発生する例外に合わせて、例外クラスを指定することができます。
例外を処理の途中で発生させる(raise)
上記までは、コード実行時に例外が起こったときに、例外処理に移って処理をするようなコードを記載しました。
raiseを使うことで、ソースコードの任意の場所で例外を発生させて、exceptブロック配下に処理を移すことができます。
try:
print("1. 例外のテストです")
print("2. 例外のテストです")
raise Exception("例外発生!!")
print("3. 例外のテストです")
except Exception as error:
print(error)
tryブロックの配下が例外処理をする対象です。
最初にprint関数で2回文字列を出力しています。
その後にraiseを使って、Exceptionクラスの例外を発生させました。
Exceptionに渡しているのが例外のメッセージです。
例外が発生したあとは、exceptブロック配下の処理に移ります。
print関数で、メッセージを表示させて処理を終えています。
出力結果を確認すると、下記のようになります。
1. 例外のテストです
2. 例外のテストです
例外発生!!
最初の2回のメッセージは出力されています。
次の処理で例外を発生させexcept配下に処理が移って、作成した例外のメッセージが表示されたことが確認できました。
例外をtryの途中で発生させたので、「3. 例外のテストです」は出力されていませんね。
エラーが発生しなかった時の処理ブロック(else)
elseブロックを用意すると、tryブロックの中でエラーが発生しなかった場合のみに実行できます。
例えば、下記のように使うことができます。
try:
print("処理開始...")
divisionByZero = False
if divisionByZero:
result = 100 / 0
except ZeroDivisionError:
print("ゼロ除算エラー")
else:
print("エラーなく処理が終了")
tryブロックの中で、最初に文字列を出力しています。
その次にdivisionByZero変数にFalseを代入しました。
Falseなので、次のif文の処理は行われずに、正常に処理が終了します。
正常終了するので、最後にelseブロックの処理が行われます。
結果、下記の2行が出力されます。
処理開始...
エラーなく処理が終了
もしもdivisionByZero変数がTrueだった場合には、0除算エラーが発生します。
そのため、exceptブロックに処理が移行して、elseブロックは実行されずに処理が終わります。
結果、下記が出力されました。
処理開始...
ゼロ除算エラー
このようにエラーが発生していない時だけ、最後に実行してくれるのがelseブロックです。
最後に実行される処理ブロック(finally)
finallyブロックは、tryブロックでエラーが発生しても、発生しなくても実行される処理を書きます。
例えば、下記のように使うことができます。
try:
print("処理開始...")
divisionByZero = True
if divisionByZero:
result = 100 / 0
except ZeroDivisionError:
print("ゼロ除算エラー")
else:
print("エラーなく処理が終了")
finally:
print("処理終了...")
先ほどのプログラムを少し修正して、finallyブロックを追加しました。
最初に開始メッセージを出力して、divisionByZero変数の値をTrueにしています。
if文の処理を通るので、0除算されて、exceptブロックの処理に移行します。
そして異常時のメッセージを出力して、finallyブロックで終了メッセージを出力するといった形です。
出力結果は下記のようになります。
処理開始...
ゼロ除算エラー
処理終了...
finallyブロックの処理が実行されています。
divisionByZero変数の値をFalseにしたときには下記のようになります。
処理開始...
エラーなく処理が終了
処理終了...
このように、正常処理のelseブロックを通った後に、finallyブロックが実行されます。
異常があっても、正常終了でも実行されていることが確認できました。
例外処理の内容まとめ
最後にtry/except/else/finallyについてまとめました。
| 項目 | 内容 |
|---|---|
| try | 例外処理の対象にしたいコードブロックの先頭に書く。 |
| except | tryブロックでエラーになった場合の処理を書く。例外クラスを指定して、例外発生時に処理の遷移先を振り分けることが可能。 |
| else | tryブロックでエラーにならなかった場合の処理を書くことができる。 |
| finally | tryブロックでエラーになっても、エラーにならなくても最後に実行される処理を書ける。 |

コメント