例外処理

 プログラミングで例外とは、エラーが起きることを言います。プログラミングの間違いで起きることもあれば、ユーザーからの入力が想定外の入力によって発生することもあります。プログラミングの間違いは、直せばよいことですが、入力については防ぐことができません。したがって入力が想定外だった場合の処理をあらかじめ決めておく必要があります。そのための記述を例外処理と言います。

 エラーを発生させてみる

 エラーを発生させる一番簡単ものは除算で0で割ってみることです。
 インタラクティブシェルを使ってやってみましょう。

 >>> 1/0
 Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 ZeroDivisionError: 0 で除算しようとしました。

 親切に教えてくれます。ではスクリプトファイルに書いてみましょう。

# coding: shift-jis

print 1.0/0

raw_input()

 何も表示されなかったですね。あたかもパソコンが壊れてしまったのような動作です。ではこのエラーに対する処理の記述の仕方を説明します。

 例外処理の書き方

 今までの命令の書式と違い、いくつかのブロックに分かれます。
書式 説明
try: エラーが発生する可能性があるブロック
except: エラーが発生した際の処理が記述されているブロック
else: エラーが発生しなかった際の処理が記述されているブロック
finally: エラーが発生してもしなくても、必ず行う処理が記述されているブロック

実際の使用方法は次の通りです。

# coding: shift-jis
# 注:このコードはコピー&ペーストしても動きません。手で入力してください。

print "エラーが発生する場合"
try:
#わざとエラーを発生させます。
  print 1.0/0

except:
  print "エラーが発生しました。"

else:
  print "エラーは発生しませんでした。"

finally:
print "これでプログラム終了です。"

raw_input()

#エラーではない場合
print "エラーではない場合"
try:
  print 1.0/2.0

except:
  print "0 で除算しようとしました。"

else:
  print "エラーは発生しませんでした。"

finally:
  print "これでプログラム終了です。"

raw_input()

出力画面:
 エラーが発生する場合
 エラーが発生しました。
 これでプログラム終了です。
 
 エラーではない場合
 0.5
 エラーは発生しませんでした。
 これでプログラム終了です。
例外処理の流れがわかりますか。
それではちょっと応用です。

 except 例外クラス名:

 『クラス』というのは、まだ説明していませんが、例外クラス名とは、インタラクティブシェルでエラーを発生させたときに”ZeroDivisionError: 0 で除算しようとしました。”とIron Pythonが出力しましたが、”ZeroDivisionError”が例外クラス名になります。発生したエラーにより、処理を変更したい場合に使います。
 例を見てみましょう

# coding: shift-jis
# 注:このコードはコピー&ペーストしても動きません。手で入力してください。

print "エラーが発生する場合"
try:
#わざとエラーを発生させます。
  print 1.0/0

# ZeroDivisionErrorが発生した時の処理を記述
except ZeroDivisionError:
  print " 0 で除算しようとしました。"

except:
  print "エラーが発生しました。"

else:
  print "エラーは発生しませんでした。"

finally:
  print "これでプログラム終了です。"

raw_input()

出力画面:
 エラーが発生する場合
  0 で除算しようとしました。
 これでプログラム終了です。
 ZeroDivisionError専用の例外処理が行われて、”except:”ブロックは行われなくなりました。ここで例外ブロックの順番も重要です。次の場合はどうなるでしょう。

# coding: shift-jis
# 注:このコードはコピー&ペーストしても動きません。手で入力してください。

print "エラーが発生する場合"
try:
#わざとエラーを発生させます。
  print 1.0/0

except:
  print "エラーが発生しました。"

# ZeroDivisionErrorが発生した時の処理を記述
except ZeroDivisionError:
  print " 0 で除算しようとしました。"


else:
  print "エラーは発生しませんでした。"

finally:
  print "これでプログラム終了です。"

raw_input()

 また何も表示せず、壊れたようにすぐ消えてしまいました。なぜでしょう。
 Iron Pythonはスクリプトファイルを上から読んでいくので、こんな感じで読んでいます。
「おっ、try文がある。なになに、1を0で割るのか、もしうまくいかなかった場合はexceptブロックを実施すると。さて、但し、ZeroDivisionErrorの場合は次の処理をする・・・。えー、そんなことは先に言ってくれよー。」
 ということで拗ねちゃって、エラーを発生させています。
コンピュータって、同じことを繰り返し正確にやることは得意ですが、融通が利かずちょっとしたことで分からんとエラーを発生させる。本当に頭が悪いと思います。(笑)