【Python】エラー発生時にプログラムを止めないで続ける方法:例外処理(try、except)

時計 2021.05.16 / 時計

【Python】エラー発生時にプログラムを止めないで続ける方法:例外処理(try、except)

本記事では、Pythonプログラムでエラー発生時に、処理を止めずに続行させる方法について解説していきます。

エラー(例外)によるプログラムの異常終了をさせないためには、例外処理を行います。

例外処理では、tryやexcept、else、finallyなどを組み合わせて使用します。

Pythonでプログラムを作成する上で必須の知識ですので、本記事で理解を深めていただければと思います。

エラー発生時のプログラムの動き

Pythonプログラムでエラーが発生すると、なにも処理を施していないプログラムでは異常終了してしまいます。
これは言い換えると、エラー発生後にプログラムの処理が途中でストップするということです。

本サイトでもいくつかエラーについて解説していますが、エラーには様々な種類があります。
例えば0で数値を割ると発生するZeroDivisionErrorや、リストやタプルのインデックスの不備で発生するIndexErrorなどがあります。

Pythonでどういったエラーがあるのか気になる方は、以下に記す本サイトのエラー解説記事をご覧になってみてください。

エラーが発生するとプログラムの処理は途中で止まり、それ以降のコードは実行されません。

ですが本番環境で使用しているプログラムが、エラーが発生するたびに動作が止まるのはよろしくないです。

Pythonにはプログラムがエラー(例外)を検出したら、処理を止めることなくプログラムを継続する例外処理という方法があります。

例外処理

例外とは

Pythonで発生するエラーには、大きく分けると構文エラーと例外の2種類があります。

このうち例外とは、プログラムの構文(文法)は正しいけど、実行中に発生するエラーのことを言います。

例外が発生すれば、なにも施していないプログラムの処理はもちろん止まってしまいます。

構文エラーと例外ついての詳しい解説は以下記事をご参照ください。

例外処理とは

例外処理とは、例外が発生してもプログラムの処理を止めずに、プログラムの処理を継続させるための方法です。

プログラムを作成する上で、例外が発生する可能性のあるコードには、例外処理を行い、例外が発生してもプログラムが止まらないようにすることが重要です。

例外処理の記述には、tryやexceptなどを使用します。
これらで例外をキャッチして、例外発生したときの処理を記述するのです。

いわば例外処理とは、「プログラム実行中に例外が発生した場合に、プログラムを止めないように、どのような処理を行うかを記述すること」を意味します。

例外処理の記述:try、except

try, except

例外処理には、tryとexceptで例外をキャッチして処理できます。

try節には、例外が発生する可能性があるコード群を書きます。
except節には、例外が発生した場合の処理を書きます。

例えば、ある数値を0で割るとZeroDivisionErrorが発生します。

def divide(x):
    print(54/x)

divide(2)
divide(0)
divide(3)
# 27.0
# ZeroDivisionError: division by zero

上記では、divide(0)で例外が発生し、その後の処理が止まっていることがわかります。

これに例外処理を加えると次のようになります。

def divide(x):
    try:
        print(54/x)
    except ZeroDivisionError:
        print("ZeroDivisionError")

divide(2)
divide(0)
divide(3)
# 27.0
# ZeroDivisionError
#18.0

try節で例外(ZeroDivisionError)が発生すると、except節にプログラム実行が移り、そして最後まで処理が継続していることがわかります。

exceptのあとには、キャッチする例外名を指定する必要があります。

except 例外名:

複数の例外

発生する例外は一つだけと限られることは少ないです。

そのため想定される複数の例外をキャッチするため、以下のように複数exceptを記述することができます。

def divide(x):
    try:
        print(54/x)
    except ZeroDivisionError:
        print("ZeroDivisionError")
    except TypeError:
        print("TypeError")

divide('zero')
divide(0)
divide(3)
# TypeError
# ZeroDivisionError
# 18.0

上記の2つのexceptは、タプルを使って一つにまとめることもできます。

Except (ZeroDivisionError, TypeError):
    Print("Error")

エラーメッセージの表示:例外オブジェクト

except文は次のように記述することもできます。

except 例外名 as 変数名:

このように記述すると、発生した例外の例外オブジェクトが変数に格納されます。
例外オブジェクトには、エラーメッセージが格納されているため、エラーの詳細を知るのに非常に便利です。

def divide(x):
    try:
        print(54/x)
    except ZeroDivisionError as e:
        print(e)

divide(2)
divide(0)
divide(3)
# 27.0
# division by zero
# 18.0

すべての例外

どの例外が発生するかわからない場合や、すべての例外をキャッチしたい場合は、次のように記述します。

def divide(x):
    try:
        print(54/x)
    except Exception as e:
        print(e)

divide('zero')
divide(0)
divide(3)
# unsupported operand type(s) for /: 'int' and 'str'
# division by zero
# 18.0

上記では例外名にすべての例外を表すException(基底クラスException)を指定することで、すべての例外をキャッチしています。

except Exception as e:

Exceptionでは、sys.exit()によるSystemExitや、KeyboardInterruptなどはキャッチしません。

こういった例外も含めて、本当にすべての例外をキャッチしたい場合は、例外名を記述しません。

except:

例外処理の記述:else

else節で記述した処理は、try節で例外が発生しないで正常終了した場合に実行されます。

言い換えると、try節で例外が発生し、except節が実行された場合はelse節は実行されないということです。

def divide(x):
    try:
        x = 54/x
    except Exception as e:
        print(e)
    else:
        print(x)

divide(1)
divide(0)
divide(3)
# 54.0
# division by zero
# 18.0

例外処理の記述:finally

finally節で記述した処理は、例外が発生してもしなくても、例外の有無に関わらず必ず最後に実行されます。

else節は例外が発生した場合は実行されませんでしたが、finally節は例外発生時でも実行されるという違いがあります。

def divide(x):
    try:
        x = 54/x
    except Exception as e:
        print(e)
    finally:
        print(x)

divide(1)
divide(0)
divide(3)
# 54.0
# division by zero
# 0
# 18.0

例外を発生させる:raise

Raiseを使用することで、自分で例外を発生させることができます。

raise 例外(エラーメッセージ)

以下に例を記します。

def divide(x):
    try:
        x = 54/x
        raise TypeError("TypeErrorが発生しました(テスト)")
    except TypeError as e:
        print(e)
    finally:
        print(x)

divide(3)
# TypeErrorが発生しました(テスト)
# 18.0

まとめ

本記事「【Python】エラー発生時にプログラムを止めないで続ける方法:例外処理(try、except)」はいかがでしたか。

本記事で紹介した例外処理をまとめると次のようになります。

try:
  # 例外が発生する可能性のあるコード
except 例外名 as 変数:
  # 例外が発生した際に実行する処理
except Exception as e:
  # 上記exceptで指定した例外以外が発生した場合に実行される処理
else:
  # 例外が発生しなかった場合に実行される処理
finally:
  # 例外の有無に関わらず必ず最後に実行される処理

基本的には上記の流れで例外処理を記述していきます。

アプリケーションを開発していると、意図しない場所でエラー(例外)が発生することが多々あります。

実際の業務(本番環境)で使用されているアプリケーションは、エラーで処理が止まってしまうのもよくないですし、そのエラー内容がわからないというのもよくないです。

そのため例外処理を行って、処理が止まることないようにするのと、エラー内容がわかるようにするためにも、例外が発生しうるコードに対して使用するようにしましょう。