【Python連載】例外の種類ごとに処理を分ける


プログラム実行時のエラー(例外:exception)に対処するためのコードを組み込んだtry文~except文について、今回は例外の種類により処理の内容を変更する方法を紹介します。


複数の例外が発生する可能性のあるプログラム

本題に入る前に、まずは複数の種類の例外が発生する可能性のある簡単なプログラムを見てみましょう。
input()で2つの数を入力して、1番目に入力した数を2番目に入力した数で割る、というような割り算プログラムです。

print("1番目に入力された数を、2番目に入力された数で割ります")
first_input_value = input("1番目の入力(数字を入力してください):")
second_input_value = input("2番目の入力(数字を入力してください):")

a = int(first_input_value)
b = int(second_input_value)
print(a / b) 
※出力結果1
C:\Python> python 5-2-1.py
1番目に入力された数を、2番目に入力された数で割ります
1番目の入力(数字を入力してください):1
2番目の入力(数字を入力してください):0
Traceback (most recent call last):
File “C:\Python> python 5-2-1.py”, line 7, in <module>
print(a / b)
ZeroDivisionError: division by zero
※出力結果2
C:\Python> python 5-2-1.py
1番目に入力された数を、2番目に入力された数で割ります
1番目の入力(数字を入力してください):ぱいそん
2番目の入力(数字を入力してください):3
Traceback (most recent call last):
File “C:\Users\school\text\python 5-2-1.py”, line 5, in <module>
a = int(first_input_value)
ValueError: invalid literal for int() with base 10: ‘ぱいそん’

出力結果1では、割る側の数を0と入力してしまったため、
7行目 print(a / b)
の部分でZeroDivisionErrorが発生しています。

出力結果2では、数字を入力すべきところを文字(今回は”ぱいそん”という文字)をしてしまったので、
5行目 a = int(first_input_value)
の部分でValueErrorが発生しています。
※ValueErrorとは、関数で受け取る引数が不適切な値であった場合に発生してしまうような例外です。今回の場合だと、int()関数に”ぱいそん”というような整数に変換出来ない文字を渡してしまったため発生しました。

では、上記のプログラムを、try文~except文で異常終了しないようにしてみましょう。

print("1番目に入力された数を、2番目に入力された数で割ります")
first_input_value = input("1番目の入力(数字を入力してください):")
second_input_value = input("2番目の入力(数字を入力してください):")
try :
    a = int(first_input_value)
    b = int(second_input_value)
    print(a / b) 
except :
    print("エラーが発生しました!")

これで、プログラムが異常終了することはありません。
ですが、これだと確かに異常終了はしていませんが・・・どのような例外が発生しても同じ処理しか出来ない形になっています。
※0での割り算や文字のint型変換が発生しても、
print(“エラーが発生しました!”) が実行されるのみ

では、発生する例外の種類によって、処理を分けてみましょう。

例外の種類で処理を分ける

それでは、例外の種類により処理の内容を変更してみましょう。

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

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

では、上記書式の例外1としてValueErrorを、例外2としてZeroDivisionErrorを受け取るようにして、プログラムを見てみましょう。

print("1番目に入力された数を、2番目に入力された数で割ります")
first_input_value = input("1番目の入力(数字を入力してください):")
second_input_value = input("2番目の入力(数字を入力してください):")
try :
    a = int(first_input_value)
    b = int(second_input_value)
    print(a / b) 

except ValueError :
    print("文字を整数に変換できません。文字を入力しないでください!")

except ZeroDivisionError :
    print("ゼロで割り算は出来ません。2番目の入力を0にしないで下さい!")
※出力結果1
C:\Python> python 5-2-2.py
1番目に入力された数を、2番目に入力された数で割ります
1番目の入力(数字を入力してください):1
2番目の入力(数字を入力してください):0
ゼロで割り算は出来ません。2番目の入力を0にしないで下さい!
※出力結果2
C:\Python> python 5-2-2.py
1番目に入力された数を、2番目に入力された数で割ります
1番目の入力(数字を入力してください):ぱいそん
2番目の入力(数字を入力してください):3
文字を整数に変換できません。文字を入力しないでください!

発生した例外の種類によって、実行されるexceptブロックが変わります。
今回は、ZeroDivisionErrorが発生した場合と、ValueErrorは発生した場合で、print()で出力される内容(注意メッセージ)を変えました。

いかがでしたでしょうか。
自分でプログラムを作成する際には、どのような種類の例外が発生し得るかを検討して、例外処理を記述するようにしましょう。

以上が、例外の種類により処理の内容を変更する方法でした。


まとめ

try文~except文では、プログラム実行時に発生する例外の種類毎に、処理を記述することができます。


確認問題

合計1万円の商品を複数人で購入する際に、1人当たり何円になるかを計算するプログラムを作成しましょう。
・人数はinput()関数で入力しましょう。
・1円未満の端数(小数点)は、round()関数で四捨五入しましょう。
⇒round(値) の書式で、小数点を四捨五入して表すことができます。

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

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にしないで下さい!")
  • このエントリーをはてなブックマークに追加

PAGE TOP