Pythonではエラーは例外として扱われる。プログラム実行時にtry文を使って例外を処理する基礎をまとめて紹介する。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
# サンプルとして使用する例外クラスと例外を発生する関数の定義
class SampleError0(Exception):
pass
class SampleError1(Exception):
pass
class SampleError2(Exception):
pass
def raise_exception():
x = input('input 0 to 2: ')
if x == '0':
raise SampleError0('sample error #0')
elif x == '1':
raise SampleError1('sample error #1')
elif x == '2':
raise SampleError2('sample error #2')
else:
pass
# try文の全体構造
try:
# 例外を発生する可能性のあるコード
raise_exception()
except SampleError0:
# 捕捉した例外(ここではSampleError0)を処理
print('sample error #0 raised')
except SampleError1 as e:
# 捕捉した例外(ここではSampleError1)を処理
# 発生した例外についての情報はeから取得できる
print(e)
# except Exception as e:
# # 例外が発生したが、それをexcept節で捕捉しないと再送出される
# print(e)
else:
# 例外が発生しなかったときに実行される
print('in else: no exception')
finally:
# 例外の発生の有無に関係なく例外処理の最後に実行される
print('in finally')
# シンプルな形:try文のexcept節で例外を捕捉する
try:
# 例外を発生するかもしれないコード
raise IndexError('sample exception')
except IndexError as e:
print(e)
# 複数の例外が発生する可能性がある場合
try:
raise_exception()
except SampleError0:
print('sample error #0 raised')
except SampleError1:
print('sample error #1 raised')
except Exception as e: # Exceptionクラスで他の例外を全て捕捉
print(e)
# Exceptionクラスを最初に捕捉してはいけない
try:
raise_exception()
except Exception as e: # Exceptionクラスで全ての例外を全て捕捉してしまう
print(e)
except SampleError0:
print('sample error #0 raised')
except SampleError1:
print('sample error #1 raised')
# 複数の例外を1つのexcept節で処理する
try:
raise_exception()
except (SampleError0, SampleError1) as e:
print(type(e))
except SampleError2 as e:
print(type(e))
# 例外処理の最後に何か処理をしたい
try:
raise_exception()
except SampleError0 as e:
print(e)
except SampleError1 as e:
print(e)
except SampleError2 as e:
print(e)
finally:
print('exception handling has done')
# try節で例外が発生しなかった場合に何か処理をしたい
try:
pass
except Exception as e:
print(e)
else:
print('no exception raised')
finally:
print('exception handling has done')
Pythonではプログラムの実行時に発生するエラーを「例外」と呼ぶ。例外はその場で対処することでプログラムの動作を続行できることもあれば、対処は不可能でプログラムの動作を中断させることもある。例外に対処することを「例外処理」といい、Pythonではtry文に例外を発生させる可能性があるコードと、例外が発生した際に行う処理を記述していく。
なお、本稿では以下のような例外クラス(Exceptionクラスの派生クラス)と例外を発生させる可能性のある関数を定義する。
class SampleError0(Exception):
pass
class SampleError1(Exception):
pass
class SampleError2(Exception):
pass
def raise_exception():
x = input('input 0 to 2: ')
if x == '0':
raise SampleError0('sample error #0')
elif x == '1':
raise SampleError1('sample error #1')
elif x == '2':
raise SampleError2('sample error #2')
else:
pass
raise_exception関数ではキーボードからの入力を受け取り、その値が'0'、'1'、'2'のいずれかであればSampleError0、SampleError1、SampleError2のいずれかの例外クラスを発生させる。それ以外の値であれば、例外を発生させることなく終了するようになっている。
try文での例外処理は次のようになる。
コードで概要を示すと次のようになる。
try:
# 例外を発生する可能性のあるコード
raise_exception()
except SampleError0:
# 捕捉した例外(ここではSampleError0)を処理
print('sample error #0 raised')
except SampleError1 as e:
# 捕捉した例外(ここではSampleError1)を処理
# 発生した例外についての情報はeから取得できる
print(e)
# except Exception as e:
# # 例外が発生したが、それをexcept節で捕捉しないと再送出される
# print(e)
else:
# 例外が発生しなかったときに実行される
print('in else: no exception')
finally:
# 例外の発生の有無に関係なく例外処理の最後に実行される
print('in finally')
except節では「except 例外クラス:」とその節で処理する例外の種類だけを書いてもよいが(上の例の「except SampleError0:」)、発生した例外についての詳細な情報を必要とするのであれば「except 例外クラス as 例外オブジェクト名:」のようにすることで、try節で発生した例外についての情報を持つ例外オブジェクトを変数に代入できる。これにより、except節の内部でそのオブジェクトを使用できる(上の例の「except SampleError1 as e:」が該当する)。
この例ではSampleError0例外とSampleError1例外は処理しているが、SampleError2例外を処理するコードがない(「except Exception as e:」節がコメントアウトされていなければそこで処理される)。そのため、raise_exception関数でSampleError2例外が発生するとこのtry文では処理ができず、プログラムの制御においてさらに上位の層へと例外が再送出される。
例えば、このtry文が何かの関数のコードであれば、その関数を呼び出した側に例外が伝播する。あるいは、これがトップレベルで実行されているのであれば、SampleError2例外が再出された時点でプログラムの実行が中断される。
以下では例外処理の例を幾つか紹介していこう。
一番シンプルなのは、単一の例外を捕捉して処理するコードだろう。以下はその例だ。
try:
raise IndexError('sample exception')
except IndexError as e:
print(e) # sample exception
この例ではtry節でIndexError例外を発生させ、except節ではそれを処理している。except節は「except IndexError as e:」となっているので、その内部では例外オブジェクトeを使用して、例外送出時に設定された「sample exception」を取り出せている。
Copyright© Digital Advantage Corp. All Rights Reserved.