Python 入門 ノート (54)例外処理

例外処理

例えば次のようなエラー(今回は IndexError)が起こるとします。

l = [1, 2, 3]
i = 5
l[i]

リスト l の要素は 1,2,3の3つですが、i = 5 で6番目の要素を指定していますね。

Traceback (most recent call last):
File "/home/ec2-user/environment/Myapp.py", line 3, in <module>
l[i]
IndexError: list index out of range

すると、リストの範囲外(list index out of range)をしていしていると IndexError が表示されます。

結果、もし後にプログラムが続いている場合は、プログラム実行は途中で終了され中断されます。

try:   except:

プログラム実行の終了を避けるには次のようにします。

l = [1, 2, 3]
i = 5

try:
    l[i]
except:
    print("Don't worry")

結果は

Don't worry

が出力され、プログラム実行の終了は避けられました。

ちなみに、except は除外するという意味合いです。

Exception の種類

try:   except IndexError:

エラーには種類があります。

今回の様に、IndexError のみを避けたい場合、明示的に次のようにも書いても同じ結果が得られます。

try:
    l[i]
except IndexError:
    print("Don't worry")

この場合、IndexError 以外ではexcept は起こりません。他のエラーではプログラムの中断が起こります。

try:   except IndexError as ex:

さらに IndexError の詳細を出力してみます。

ex という変数にエラーの種類を代入し、出力します。

l = [1, 2, 3]
i = 5

try:
    l[i]
except IndexError as ex:
    print("Don't worry : {}".format(ex))
    #print(f"Don't worry : {ex}")

結果は

Don't worry : list index out of range

list index out of rangeという(リストの範囲外)エラーと出力されました。

try:   except NameError as ex:

次に del で l を削除してみると NameError が起こります。

l = [1, 2, 3]
i = 5
del l

try:
    l[i]
except NameError as ex:
    print(ex)

結果は

name 'l' is not defined

try:   except Exception as ex:

では IndexError でも NameError でも無いものを Exception を使って出力してみます。
タプルとリストをつなげてみます。

l = [1, 2, 3]
i = 5

try:
    () + l
except Exception as ex:
    print(f"other: {ex}")

結果は

other: can only concatenate tuple (not "list") to tuple

concatenate (連結)出来ないエラーが生じました。

 

python の documentation ページの 例外階層(Exception hierarchy)を見てみます。

BaseException > Exception > NameError + IndexError

上記のツリー構造が見て取れます。

Exception はほとんどのエラーを含んでいることがわかります。

但し、この使い方は推奨されていません。エラーを特定できないままプログラムを前に進めていくことは良くないこととされています。

try:   finally:

finally はエラーが起きていても、必ず実行されます。

l = [1, 2, 3]
i = 5

try:
    l(i)
finally:
  print('clean up')

finally: で clean up を出力してみます。

clean up
Traceback (most recent call last):
File "/home/ec2-user/environment/Myapp.py", line 5, in <module>
l[i]
IndexError: list index out of range

IndexError が起きているにもかかわらず、先に clean up が出力されます。

try:   except:   else:

例外処理が行われない場合、else: 処理が行われます。

例えば、リスト l の 0 番目のインデックスが呼ばれた場合、エラーが起きないので else: に飛びます。

すると clean up の前に Don’t worry が出力されます。

l = [1, 2, 3]
i = 5

try:
    l[0]
except: 
    print("Don't Worry")
else:
    print('done')
finally:
    print('clean up')
done
clean up

 

コメント