例外処理
必ず必要な機能ではないが、例外処理があると例外として通知した上で通常の処理に戻ることが出来る
isnumericメソッド
文字列が数字だけで構成されているのかチェックしてくれる
# 価格(price)と人数(count)を入力して価格を人数で割って整数で表示する
while True:
price = input('price: ')
if not price.isnumeric():
print('Input an integer')
print('-'*20)
continue
count = input('count: ')
if not count.isnumeric():
print('Input an integer')
print('-'*20)
continue
price = int(price)
count = int(count)
if count == 0:
print('The count must be != 0')
print('-'*20)
continue
print('price//count=',price//count)
print('-'*20)
price: 3000
count: 2
price//count= 1500
--------------------
price: 1.23
Input an integer
--------------------
price: 3000
count: 3.4
Input an integer
--------------------
price: 4999
count: 0
The count must be != 0
--------------------
try文とexcept節
try文は例外が発生する可能性のある処理を複数の文に渡って書ける
except節は例外処理の対象にしたい例外(例外クラス)を指定する
# 価格(price)と人数(count)を入力して価格を人数で割って整数で表示する
while True:
try:
price = int(input('price: '))
count = int(input('count: '))
print('price//count=',price//count)
except ValueError:
print('Input an integer')
except ZeroDivisionError:
print('The count must be != 0')
print('-'*20)
price: 1000
count: 2
price//count= 500
--------------------
price: 1.23
Input an integer
--------------------
price: 3000
count: 3.14
Input an integer
--------------------
price: 3000
count: 0
The count must be != 0
--------------------
めっちゃ短くなった
except節の色んな書き方
複数の例外を1つのexcept節にまとめる
# 価格(price)と人数(count)を入力して価格を人数で割って整数で表示する
while True:
try:
price = int(input('price: '))
count = int(input('count: '))
print('price//count=',price//count)
except (ValueError,ZeroDivisionError):
print('Error.')
print('-'*20)
price: 1.23
Error.
--------------------
price: 3000
count: 0
Error.
--------------------
except節にて複数の例外を指定すると更に短くできる
あらゆるエラーをまとめる
# 価格(price)と人数(count)を入力して価格を人数で割って整数で表示する
while True:
try:
price = int(input('price: '))
count = int(input('count: '))
print('price//count=',price//count)
except:
print('Error.')
print('-'*20)
エラー内容を指定しないとあらゆるエラーを例外として処理してくれる
便利そうに見えて実は大きな欠陥がある
KeyboardInterruptエラーも例外として処理してしまうため、上記のプログラムは終了できない
この場合、Exceptionという例外(例外クラス)を指定することでプログラムをきちんと終了できるようになる
# 価格(price)と人数(count)を入力して価格を人数で割って整数で表示する
while True:
try:
price = int(input('price: '))
count = int(input('count: '))
print('price//count=',price//count)
except Exception:
print('Error.')
print('-'*20)
price: 2000
count: 2
price//count= 1000
--------------------
price: 2000
count: 1.2
Error.
--------------------
price: 12.2
Error.
--------------------
price: 2000
count: 0
Error.
--------------------
これで良いように見えるが、実はよろしくない点が一つある
それが例外の内容がわからない点である
そこでExceptionの内容を変数eに格納することができる
# 価格(price)と人数(count)を入力して価格を人数で割って整数で表示する
while True:
try:
price = int(input('price: '))
count = int(input('count: '))
print('price//count=',price//count)
except Exception as e:
print(e)
print('-'*20)
price: 1.23
invalid literal for int() with base 10: '1.23' # 例外の内容を出力
--------------------
price: 1000
count: 0
integer division or modulo by zero # 例外の内容を出力
--------------------
finally節
finally節は例外の発生に関わらず実行する処理を記載する
# 価格(price)と人数(count)を入力して価格を人数で割って整数で表示する
while True:
try:
price = int(input('price: '))
count = int(input('count: '))
print('price//count=',price//count)
except Exception as e:
print(e)
finally:
print('-'*20)
price: 1000
count: 0
integer division or modulo by zero
--------------------
price: 1.23
invalid literal for int() with base 10: '1.23'
--------------------
price: -------------------- # finally節の処理
Traceback (most recent call last):
実はもとの実行結果と最後が異なる
price: 1.23
invalid literal for int() with base 10: '1.23'
--------------------
price: 1000
count: 0
integer division or modulo by zero
--------------------
price: Traceback (most recent call last): # この部分がことなる
finally節を使うことでfinally節以降の処理が実行されたうえでプログラムが終了する
else節
例外が発生しなかったときの処理
except節より後にfinally節より前に書く
# 価格(price)と人数(count)を入力して価格を人数で割って整数で表示する
while True:
try:
price = int(input('price: '))
count = int(input('count: '))
print('price//count=',price//count)
except Exception as e:
print(e)
else:
print('Perfect!')
finally:
print('-'*20)
price: 1000
count: 2
price//count= 500
Perfect!
--------------------
raise文
意図的に例外を発生させる
# 価格(price)と人数(count)を入力して価格を人数で割って整数で表示する
while True:
try:
price = int(input('price: '))
if price < 0:
raise Exception('The price must be >= 0')
count = int(input('count: '))
print('price//count=',price//count)
except Exception as e:
print(e)
else:
print('Perfect!')
finally:
print('-'*20)
price: -1000
The price must be >= 0
--------------------
raise文には次の使い方もできる
- 処理中の例外を再送出
- 処理中の例外を原因とする別の例外を発生させる
try:
1/0
except Exception as e:
print(e)
division by zero
これまでの書き方だとこんな感じ
再送出すると
try:
1/0
except Exception:
raise
例外が発生しました: ZeroDivisionError
division by zero
File "C:\Codes\Python\raise.py", line 2, in <module>
1/0
~^~
ZeroDivisionError: division by zero
except節で処理が完結せず、プログラムエラーで終了する
try:
1/0
except Exception as e:
raise Exception from e
例外が発生しました: Exception
division by zero
File "C:\Codes\Python\raise.py", line 2, in <module>
1/0
~^~
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
File "C:\Codes\Python\raise.py", line 4, in <module>
raise Exception from e
Exception:
「ZeroDivisionErrorを原因にExceptionが発生した」というエラー内容になる