【Python入門】例外処理を書く方法!(try/except)

Python Python

Pythonの例外処理についてまとめました。
最初にPythonの例外処理について解説しています。

その後に下記について書いています。

・例外を処理の任意の箇所で発生させる(raise)
・エラーが起きなかった時の処理を書く(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("エラーが発生しました。")

exceptExceptionクラスを指定しました。
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除算が発生するので、exceptZeroDivisionErrorクラスを書いている方に処理が移ります。

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

コメント

タイトルとURLをコピーしました