LoginSignup
3
3

More than 3 years have passed since last update.

Pythonの例外処理(Python学習メモ⑥)

Last updated at Posted at 2019-11-13

例外の処理

ポイント

  • まずtryを実行し、例外が発生されなければそのまま終了
  • 例外が発生した時点でtry節の残りがスキップされ、exceptで該当の型が定義されていればそのexcept節が実行される
  • 例外の型がexceptで定義した名前と一致しない場合、例外はさらに外側にあるtry文に渡される
  • ハンドラが見つからない場合は例外のメッセージを表示し、実行終了する
  • except節は例外名を省略するとき、全部の例外を対象にすることができる(あまり良い方法ではない)
import sys

try:
    f = open('myfile.txt')
    s = f.readline()
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("データが整数に変換できません。")
except:
    print("予期せぬエラー: ", sys.exc_info()[0])
    raise # 呼び出し元でキャッチできるように例外を再送出

  • タプルを使うと1つのexcept節で複数の例外を指定することができる
複数の種類の例外をキャッチ
except(RuntimeError, TypeError, NameError):
    pass
  • else節を使用することでtry節で例外が発生しなかった場合のみ実行する処理を書くことができる
  • また、except 例外名 as errのように記載するとerrには例外インスタンスが渡される
  • 例外名はerr.__str__()で参照可能
else節を追加
import sys

try:
    f = open('myfile.txt')
    s = f.readline()
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("データが整数に変換できません。")
except:
    print("予期せぬエラー: ", sys.exc_info()[0])
    raise # 呼び出し元でキャッチできるように例外を再送出
else:
    print(s)
    f.close()

例外を起こす

ポイント

  • raise 例外名(引数)で例外を強制的に発生させられる
  • except節内で単にraiseと書くと例外を再送出できる

例外を定義する

ポイント

  • 例外クラスを作成すると独自の例外を定義できる
  • 通常はExceptionクラスから派生したクラスとする
例外クラス

class MyError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

try:
    raise MyError(2*2)
except MyError as e:
    print('My exception occurred, value:', e.value)
# 出力
# My exception occurred, value: 4

raise MyError('oops!')
# 出力
# Traceback (most recent call last):
#   File ".\exception_class.py", line 12, in <module>
#     raise MyError('oops!')
# __main__.MyError: 'oops!'

try-finallyでクリーンアップ処理

ポイント

  • finally節は、例外発生の有無にかかわらず、tryを抜けるときに必ず実行される
  • try文内の他の節からbreak, continue, return文によって抜けるときも実行される
finallyの例

def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("ゼロ除算エラー")
    else:
        print('答え: ', result)
    finally:
        print('in finally')

divide(2, 1)
# 答え:  2.0
# in finally

divide(2, 0)
# ゼロ除算エラー
# in finally

divide("2", "1")
# in finally
# Traceback (most recent call last):
#   File ".\divide.py", line 15, in <module>
#     divide("2", "1")
#   File ".\divide.py", line 3, in divide
#     result = x / y
# TypeError: unsupported operand type(s) for /: 'str' and 'str'

withでクリーンアップ処理

ポイント

  • オブジェクトには標準のクリーンアップ動作が定義してあるものがある(例えばファイルオブジェクトなど)
  • with文を使う事でデフォルトのクリーンアップ処理が自動的に実行される
with open('workfile', 'r') as f:
    read_data = f.read()

print(f.closed)
# True
3
3
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
3
3