はじめに
Pythonで実行時エラーが発生したことはありませんか?
初心者の方に限らず、上級者の方でも実行時エラーと付き合っていく必要があります。
完ぺきなプログラムはほとんどありえませんので、たいていのプログラムで実行時エラーが発生するでしょう。とはいえ、プログラミング中に対処できる箇所は手をうっておくべきです。
この記事では、Python初心者の方向けに、Pythonでの例外処理についてお伝えしていきます。
例外をうまく使って、実行時エラーを未然に防ぎましょう。
例外ってなに?
例外とは、エラーに近いものですが、エラーが予期していないものであることに対して、例外は予期(予想)されたものであるという違いがあります。
エラー=例外と考えてもそれほど問題はありませんが、少し気色の違うものであることを覚えておきましょう。
簡単にいえば、エラー(例外)が発生しそうな場所であらかじめ処理を記述しておき、例外が発生したときに適切な処理を行うようにします。
問題から回復可能であれば復帰させますし、回復が不可能であれば安全にプログラムを終了させます。
次に、基本的な例外処理の構文をみていきましょう。
例外の基本的な構文
まずは、エラーが起きるプログラムを記述してみましょう。
たとえば、次のような0除算を実行するプログラムです。
例:
def divide(x, y): return x / y divide(100, 0)
非常に単純な例ですが、割り算を実行する関数に0を渡して、0除算を行っています。
このプログラムを実行すると、0除算エラー(ZeroDivisionError)が発生して停止してしまいます。
0除算は簡単に予期できるため、次のように例外処理を行うとよいでしょう。
例:
def divide(x, y): try: return x / y except ZeroDivisionError: print("0では除算できません") divide(100, 0)
tryからexceptまでの間が、例外を処理できる区間となります。
exceptには処理する例外(エラー)の型を指定し、続けて処理内容を記述します。
このようにすることで、該当する例外が発生してもプログラムの実行を継続できます。
except文は複数記述できるため、対応しなければならない例外が複数あっても大丈夫です。
また、確実に終了処理を実行するためにfinally文を使うこともできます。次の例をみて下さい。
例:
def divide(x, y): try: result = x / y print("例外は発生しませんでした") return result except ZeroDivisionError: print("0では除算できません") finally: print("終了処理") divide(100, 0) divide(100, 10)
例外が発生すると、その時点で実行フローがexcept文に移動しますので、try文では例外発生地点以降のコードが実行されません。
確実にコードを実行するために、finally文を使って終了処理などを記述します。
finally文は、正常時でも例外発生時でも実行されます。
組み込みの例外型について
先程、組み込みの例外型として” ZeroDivisionError”を使いました。
Pythonには、他にもたくさんの例外型があり、例外処理で活用できます。
たとえば、リストなどのインデックスが範囲外のときに発生する”IndexError”や不適切な型で演算を行ったときに発生する”TypeError”などです。
よく使う例外だけでも覚えておくとよいでしょう。
オリジナルの例外を定義することもできる
自分で作った関数から例外を投げる(発生させる)場合、組み込み型に適切な例外型が見つからない場合があります。
たとえば、次のような例をみてみましょう。
例:
class DateRangeError(Exception): def __str__(self): return "日付の範囲ではありません" def printDate(year, month, day): if not (year > 0 and 0 < month < 13 and 0 < day < 32): raise DateRangeError() print("{0}/{1}/{2}".format(year, month, day)) printDate(2017, 8, 10) printDate(2017, 8, 32)
この例では、日付をフォーマットして出力する関数で、日付の範囲をチェックしています。
日付の範囲から外れている場合、オリジナルの例外の”DateRangeError”を投げています。
オリジナルの例外はExceptionクラスのサブクラスとして定義し、それをraise句でインスタンス化しています。
エラー時のメッセージをよりわかりやすくするために、例のように__str__をオーバーロードしておくとよいでしょう。
なお、オリジナルの例外でもexcept文で問題なく使えます。
まとめ
例外の使い方がお分かりになりましたか?
予測できるエラーは、例外を使って捕捉するようにしましょう。
エラーから復帰できれば問題ありませんし、復帰できない場合でも適切な処理をしてプログラムを終了したりすることができます。
エラーはプログラムの敵です。適切なエラー処理を行って、堅牢なプログラムを作りましょう。