例外処理

例外処理の基本

Pythonの例外処理は他の言語と同様、例外が発生する可能性のある箇所をtryブロックに囲み、exceptで例外を補足します。

以下のコードは0で割り算した場合の例外補足のサンプルです。

x = 1000
y = 0

try:
    z = x / y
    print(z)
except ZeroDivisionError:
    print('除算に0が指定されました')

また、例外オブジェクトを指定しない場合は全ての例外を補足することができます。

例外オブジェクトの利用

例外を補足した際にasで例外オブジェクトを変数として指定し、情報を取得することができます。

except 例外クラス as 変数名

例えば例外オブジェクトの情報を参照したい場合は以下のように書きます。

try:
    z = x / y
    print(z)
except ZeroDivisionError as e:
    print('除算に0が指定されました')
    print(type(e), str(e))

例外の継承関係

例外クラスは継承関係をもっています。

BaseExceptionクラスがすべての例外の親クラスとなります。

また、次ページで説明する独自例外クラスを実装する際の親となるものがExceptionクラスです。
代表的な組込みの例外の継承関係を以下に示します。

BaseException ←全ての例外の親クラス
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception ←独自例外の親クラス
+-- StopIteration ← イテレータを使用した際に、次の値が無いのにnextした場合に発生
+-- ArithmeticError
| +-- OverflowError ← オーバーフローした場合に発生
| +-- ZeroDivisionError ← 0で除算した場合に発生
|
+-- AssertionError ← アサートエラー
+-- AttributeError ← 存在しない属性を参照した際に発生
+-- ImportError ← インポートに失敗した際に発生
+-- LookupError
| +-- IndexError ← シーケンスに対し存在しないインデックスでアクセスした場合に発生
| +-- KeyError ← 辞書位に対し存在しないキーでアクセスした場合に発生
+-- NameError
| +-- UnboundLocalError
+-- OSError ←システム関連のエラー
| +-- FileExistsError ← すでに存在するファイルやディレクトリを作成しようとした場合に発生
| +-- FileNotFoundError ← 要求されたファイルやディレクトリが存在しない場合に発生
| +-- PermissionError ← ファイルアクセス時に十分な権限がない場合に発生
| +-- TimeoutError ← システム関数がタイムアウトした場合に発生
+-- RuntimeError ← 他のどのカテゴリにも属さないエラーや不明なエラー
+-- SyntaxError ← 文法エラー
| +-- IndentationError ← 不正なインデントがある場合に発生
| +-- TabError ← タブとスペースを一貫しない方法でインデントに使っている場合に発生
+-- TypeError ← 組み込み演算、もしくは関数が適切でない型のオブジェクトに対して適用された場合に発生
+-- ValueError ← 組み込み演算や関数が、正しい型だが適切でない値を受け取った場に発生
+-- Warning ← 警告

5. 組み込み例外より抜粋

先ほどのサンプルコードではZeroDivisionErrorを使って例外を補足していましたが、(良し悪しはさておき)かわりにArithmeticErrorやExceptionを使用することも可能です。

複数の例外を補足する

param = {'x' : 1000, 'z' : 0}
try:
    x = param['x']
    y = param['y']
    z = x / y
    print(z)

except KeyError as e: # 辞書に存在しない場合の例外を補足
    print('処理に必要なデータが存在しません')

except ZeroDivisionError as e: # 0除算を補足
    print('除算に0が指定されました')

except: # 全ての例外を補足
    print('原因不明のエラーが発生しました')

else / finally

for文と同様に、tryブロック中で例外が発生しなかった場合、elseブロック内部の処理が実行されます。また、tryブロック中での例外発生有無にかかわらずfinallyブロックが実行されます。

try:
    z = x / y
    print(z)
except ZeroDivisionError as e:
    print('1')
else:
    print('2')
finally:
    print('3')

例えば、上記コードでyの値が0の場合は例外が発生するため1と3が出力されます。

また、yの値が0以外の場合は例外が起こらず2と3が出力されます。