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 ブロックでエラーになっても、エラーにならなくても最後に実行される処理を書ける。 |
コメント