プログラミングコードを実行してエラーが発生した時、Pythonは例外を使います。
例外とはエラーが起きた時に実行されるコードです。
Pythonではエラーが発生すると、エラーメッセージと発生箇所の情報を出力し、プログラムを強制終了します。
このままエラーの成り行きに任せるよりも、エラーが発生しそうな箇所に適切な例外ハンドラを設けておいて、詳細で個別な情報、処理をあらかじめ用意しておく方が運用上も便利です。
ここではPythonの例外処理の方法についてみていきましょう。
例外処理 – try 〜 except文
Pythonのコードを実行して問題があると、通常Pythonはエラーメッセージを表示してプログラミングを終了します。これまで学んで来た中でもエラーは出て来たのでどんなものかはわかると思います。
次のコードで見てみましょう。
l = ["Python", "Swift", "Java", "PHP", "JavaScript"]
i = 5
code = l[i]
print(code)
print("Python勉強中!")
リストを用意して、インデックスを指定し、リストの中身を出力します。最後にメッセージを出力するコードです。
でも、これはエラーだとわかりますよね。実行してみましょう。(ファイル名はexception.pyにしてAtomで実行しています)
なぜエラーになっているのかはわかりますよね。リストの範囲に無いインデックスを指定しているからです。
“IndexError: list index out of range” と表示されて、プログラムが強制終了されているので、最後のprint文まで出力されていません。
try 〜 except文で書く
このコードをtry 〜 except文を使って例外処理のブロックを書いてみます。
l = ["Python", "Swift", "Java", "PHP", "JavaScript"]
i = 5
try:
code = l[i]
print(code)
except:
print("リストにありません")
print("Python勉強中!")
tryとコロンの下のブロックに実行するコードを記入し、exceptとコロンの下のブロックにコードにエラーが発生したのをキャッチした時の処理を書いています。ここではコードを抜けた最後にメッセージを出力するprint文のコードを置きました。
これを実行してみましょう。
エラーをキャッチして、exceptで指定した処理を行ったあとに、最後のコードを実行しているのがわかります。エラーを表示して途中で強制終了された最初のコードとは違うのがわかりますね。
最初のコードで見た時にわかったように、このコードはインデックスエラーでした。
このインデックスエラーが起きた時だけ、上記の処理をしたい場合はexceptの後に、IndexErrorを書いて指定します。次のように書き換えてみましょう。
l = ["Python", "Swift", "Java", "PHP", "JavaScript"]
i = 5
try:
code = l[i]
print(code)
except IndexError as e:
print("リストにありません: {}".format(e))
print("Python勉強中!")
ここでは、except後ろにIndexErrorを置いて、さらにas eと書いています。さらに処理文の中に{}を書いて.format(e)と書いてます。これはprint出力の操作でこれまでに触れていない内容ですが、こういう書き方があるということだけここでは頭に入れておきましょう。エラー文を変数eに入れて、eの内容を{}の中に表示するという処理です。
このコードを実行してみましょう。
同様に処理できています。IndexErrorのメッセージを表示されています。
このコードはIndexErrorが起きた時をキャッチするコードでした。
それではインデックスエラーとは違うエラーが発生した時はどうなるでしょう。
このコードのi=5のところをm=5に変えて実行してみます。
NameError: name ‘i’ is not definedとなって、ネームエラーになっているのがわかります。
このように、異なるエラー毎にそれぞれキャッチしたい場合は次のようにexcept文を追加してコードを書きます。
l = ["Python", "Swift", "Java", "PHP", "JavaScript"]
m = 5
try:
code = l[i]
print(code)
except IndexError as e:
print("リストにありません: {}".format(e))
except NameError as e:
print("変数名がおかしいです: {}".format(e))
print("Python勉強中!")
INdexErrorとNameErrorのexcept文をそれぞれ用意しているのがわかりますね。
これを実行すると、こうなります。
NameErrorをキャッチして処理できているのがわかりますね。
例外のクラス階層を確認
例外処理についてインデックスエラーとネームエラーだけを扱って見てみました。
NameErrorなどの代わりに、Exceptinonsを置くと全ての例外をキャッチしてくれます。例外をキャッチするという意味だけでは楽ですが、どんな例外が発生しているのかわからなくなって理解の妨げになってしまいます。
ですから、例外処理をする場合に適切なものをキャッチするコードを書くために、例外クラスの階層を確認して必要な処理を設定するのがいいでしょう。
finallyで必ず実行
例外が発生してもしなくても、必ず実行する処理というものを設定した場合もあります。そんな時はfinallyを使ってブロックコードを書きます。
先ほどのコードに、finallyを次のように加えてみます。
l = ["Python", "Swift", "Java", "PHP", "JavaScript"]
m = 5
try:
code = l[i]
print(code)
except IndexError as e:
print("リストにありません: {}".format(e))
except NameError as e:
print("変数名がおかしいです: {}".format(e))
finally:
print("どんな時も実行します!")
print("Python勉強中!")
これを実行してみましょう。
エラーをキャッチして、さらにfinallyのコードも実行していますね。
ここで例外をキャッチしないコードにしてエラーを表示さるように書き換えてみましょう。
l = ["Python", "Swift", "Java", "PHP", "JavaScript"]
m = 5
try:
code = l[i]
print(code)
finally:
print("どんな時も実行します!")
print("Python勉強中!")
これだと例外をキャッチできないのはわかりますね。
実行してみましょう。
exceptの部分をコメントアウトして実行しています。
エラーを表示していますが、その前にfinallyの部分を実行しているのがわかります。
例外が発生しない場合のelse
次は、例外が発生しない場合の処理を加えてみましょう。この場合はelseを使います。if-else文に似たような書き方ですね。
次のようにelseを加えて例外が発生していないコードを書いてみましょう。
l = ["Python", "Swift", "Java", "PHP", "JavaScript"]
i = 0
try:
code = l[i]
print(code)
except IndexError as e:
print("リストにありません: {}".format(e))
except NameError as e:
print("変数名がおかしいです: {}".format(e))
else:
print("例外発生は無いですよ!")
finally:
print("どんな時も実行します!")
print("Python勉強中!")
リストのインデックスを範囲内の0にしていますし、変数名も合っているので例外は発生しないコードになっています。
これを実行するとこうなります。
elseのブロックが処理されているのがわかりますね。例外が無いことを確認し、finallyで必ず実行されるコードが処理されて、最後にこのコードを抜けたprint文が処理されています。
まとめ
Pythonでエラーが起こると例外が発生します。この例外をうまく利用してプログラミングの処理を実行することができます。
例外処理にはtry〜except文を使ってエラーが発生した時の処理を記述します。
例外が発生してもしなくても実行するコードを利用したい場合は、finallyを使います。
例外が発生しなかった場合の処理をelse文を使って書くことができます。
例外処理を、エラーが発生しそうな場所に適切におこなって入れば、個別な情報を得たや処理を行なうことができるので有用です。