LoginSignup
0
0

Python学習6日目~例外処理

Posted at

例外処理

必ず必要な機能ではないが、例外処理があると例外として通知した上で通常の処理に戻ることが出来る

isnumericメソッド

文字列が数字だけで構成されているのかチェックしてくれる

example.py
# 価格(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節は例外処理の対象にしたい例外(例外クラス)を指定する

example.py
# 価格(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節にまとめる

example.py
# 価格(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節にて複数の例外を指定すると更に短くできる

あらゆるエラーをまとめる

example.py
# 価格(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という例外(例外クラス)を指定することでプログラムをきちんと終了できるようになる

example.py
# 価格(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に格納することができる

example.py
# 価格(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節は例外の発生に関わらず実行する処理を記載する

example.py
# 価格(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節より前に書く

example.py
# 価格(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文

意図的に例外を発生させる

example.py
# 価格(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文には次の使い方もできる

  • 処理中の例外を再送出
  • 処理中の例外を原因とする別の例外を発生させる
example.py
try:
    1/0
except Exception as e:
    print(e)
実行結果
division by zero

これまでの書き方だとこんな感じ
再送出すると

raise.py
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節で処理が完結せず、プログラムエラーで終了する

raise.py
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が発生した」というエラー内容になる

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0