Developer

【Python独学】エラー情報を受け取るasの使い方
2020.11.02
Lv1

【Python独学】エラー情報を受け取るasの使い方

プログラム実行時のエラー(例外:exception)に対処するためのコードを組み込んだtry文~except文について、今回は発生した例外の情報を受け取るasキーワードの使い方について紹介します。


asキーワードの使い方について

try文内での処理で例外が発生すると、exceptブロックが実行されますが・・・実はこれは、例外発生時には例外オブジェクトが発生し、それをexceptブロックで受け取ることでexceptブロックが実行される、というような形になっています。
その際の例外オブジェクトを変数に代入することが出来る、というのがasキーワードの役割になります。

以下が、書式となります。

try:
    例外が発生する恐れのある処理
                   ・・・
except 例外1 as 変数名:
    例外1が発生したら実行する処理
                   ・・・
except 例外2 as 変数名:
    例外2が発生したら実行する処理
                   ・・・

例外オブジェクトを変数に代入しておくことで何が出来るのかと言うと・・・それは、例外についての情報が出力できるという点があります。
では、実際に例を見てみましょう。

print("占い開始")
fortunelist = ["大吉","吉","大凶"]

try :
    input_value = int(input("0~2のうち、好きな数字を入力してください:"))
    print(fortunelist[input_value]) 

except ValueError as error:                                           #asキーワードの使用
    print("文字を入力しないでください!")
    print(error)

except IndexError as error: 
    print("0~2以外の範囲の数字は無効です。0~2の数字を入力してください!")
    print(error)                                                      #asキーワードの使用
※出力結果1
C:\Python> python 5-4-1.py
占い開始

0~2のうち、好きな数字を入力してください:3
0~2以外の範囲の数字は無効です。0~2の数字を入力してください!
list index out of range

※出力結果2
C:\Python> python 5-4-1.py
占い開始

0~2のうち、好きな数字を入力してください:ぱいそん
文字を入力しないでください!
invalid literal for int() with base 10: ‘ぱいそん’

上記の出力結果を見ると、例外発生時に出力されるようなメッセージがありますね。
このように、どのような例外なのかという情報を出力することが出来ました。

なお、asキーワードで指定した変数は、exceptブロックを抜けると破棄されます。
実際に、ブロックの外で出力を試してみましょう。

print("占い開始")
fortunelist = ["大吉","吉","大凶"]

try :
    input_value = int(input("0~2のうち、好きな数字を入力してください:"))
    print(fortunelist[input_value])

except ValueError as error:
    print("文字を入力しないでください!")
    print(error)

except IndexError as error:
    print("0~2以外の範囲の数字は無効です。0~2の数字を入力してください!")
    print(error)

print(error)                                                             #try文~except文ブロックの外で実行
C:\Python> python 5-4-2.py
占い開始

0~2のうち、好きな数字を入力してください:3
0~2以外の範囲の数字は無効です。0~2の数字を入力してください!
list index out of range
Traceback (most recent call last):

File “C:\Users\school\text\python 5-4-1.py”, line 16, in <module>
print(error)

NameError: name ‘error’ is not defined

このように、未定義の変数を参照しているというNameErrorが発生してしまいます。
asキーワードを使用してエラー情報を出力させる際には気を付けましょう。

以上が、例外の情報を受け取るasキーワードの使い方でした。

おまけ~例外オブジェクトについて~

例外オブジェクトの話が出たところで、例外に関して少し掘り下げた話をします。
※以下に出てくるクラスや継承という考え方の話は、今後の記事で詳しく扱います。

本記事に出てきたプログラムでは、例外としてValueErrorやIndexErrorが出てきました。
ValueErrorやIndexErrorはクラスというものであり、クラスから作られるものがオブジェクトになります。
(クラスとは、しばしば『設計図』という例えをされているようなものです)
try文での処理で例外が発生すると、その例外の種類に応じた例外オブジェクトが発生し、その例外オブジェクトをexceptブロックで受け止めることでexceptブロックが実行される、というような流れになっています。

また、ValueErrorクラスやIndexErrorクラスは、Exceptionというクラスを継承しているクラスです。
Exceptionクラスを元にValueErrorクラスやIndexErrorクラス、他にもZeroDivisionError等が定義されています。
ValueErrorやIndexErrorの例外を受け取る際には、Exceptionで受け取ることが出来ます。

実際に例を見てみましょう。

print("占い開始")
fortunelist = ["大吉","吉","大凶"]

try :
    input_value = int(input("0~2のうち、好きな数字を入力してください:"))
    print(fortunelist[input_value])

except Exception :                                                   #ValueErrorもIndexErrorも受け止める
    print("エラーが発生しました")

プログラムを実行すると、input()関数で『ぱいそん』と入力しても『3』と入力しても、どちらも同じく9行目が実行されます。
(『エラーが発生しました』という文字列出力)

次に、ValueErrorは独自に受け取れるようにしてみます。

print("占い開始")
fortunelist = ["大吉","吉","大凶"]

try :
    input_value = int(input("0~2のうち、好きな数字を入力してください:"))
    print(fortunelist[input_value])

except ValueError :                                                    #ValueErrorを受け止める
    print("文字を入力しないでください!")
    
except Exception :                                                     #ValueError以外の例外(Exception)を受け止める
    print("エラーが発生しました")

プログラムを実行すると、input()関数で『ぱいそん』と入力すると8,9行目が実行され、IndexErrorとなるような値を入力すると11,12行目が実行されます。

最後に、exceptブロックの書く順番について、注意点です。

ValueErrorを受け取るexceptブロックを作成してValueError独自の注意喚起メッセージを出力するようにしても、Exceptionで受け取るexceptブロックがプログラムでより上側に書かれている場合には、ValueError独自の注意喚起メッセージを出力をすることができません。

print("占い開始")
fortunelist = ["大吉","吉","大凶"]

try :
    input_value = int(input("0~2のうち、好きな数字を入力してください:"))
    print(fortunelist[input_value])
    
except Exception :                                                   #ValueErrorもValueError以外の例外も受け止める
    print("エラーが発生しました")

except ValueError :                                                  #ValueErrorが発生しても、こちらのブロックは実行されない
    print("文字を入力しないでください!")

プログラムを実行すると、input()関数で『ぱいそん』と入力しても、8,9行目が実行されるだけであり、11,12行目は実行されません。
例外オブジェクトが発生した際には、プログラムの上から順番に、その例外オブジェクトを受け取ることが出来るexceptブロックが存在すれば、そこのブロックで実行されてしまいますので、注意しましょう。

以上、少し長くなってしまいましたが例外オブジェクト、例外クラスに関する補足でした。


まとめ

例外発生時には例外オブジェクトが発生し、それをexceptブロックで受け取ることでexceptブロックが実行されます。
asキーワードで例外オブジェクトを変数に代入することが出来ます。


確認問題

以下のような合計1万円の商品を複数人で購入する際に、1人当たり何円になるかを計算するプログラムがあります。
asキーワードを使用して、例外に関する情報を出力してみましょう。

sum = 10000
number_of_people_value = input("何人での購入ですか?")

try :
    price = round(sum / int(number_of_people_value))
    print(price) 

except ValueError :
    print("文字を入力しないでください!")

except ZeroDivisionError :
    print("人数を0にしないで下さい!")

 

※以下が解答の一例になります。

sum = 10000
number_of_people_value = input("何人での購入ですか?")

try :
    price = round(sum / int(number_of_people_value))
    print(price) 

except ValueError as error :
    print("文字を入力しないでください!")
    print(error)

except ZeroDivisionError as error:
    print("人数を0にしないで下さい!")
    print(error)

 

連載目次

独学で学ぶ Pythonプログラミング 連載目次