Python: 例外処理

2022.7.26
Dev

raiseで例外を発生させることができる。投げられた例外はtry-exceptで捕捉することができる。

try:
  raise RuntimeError('Error occurred')
except RuntimeError as e:
  print(e)

raise

例外はBaseExceptionクラスを継承している必要がある。

raise RuntimeErrorのようにクラス名を指定すると、そのクラスが引数なしでインスタンス化され、そのインスタンスが例外として投げられる。

raise RuntimeError("Exception occurred")のようにインスタンスをそのまま渡すと、そのインスタンスが例外として投げられる。

from節を使用すると、例外を連鎖させることができる。例えば以下のコード

try:
  raise RuntimeError("Exception 1")
except RuntimeError as e:
  raise RuntimeError("Exception 2") from e

を実行すると、以下のようなTracebackが出力される。

Traceback (most recent call last):
  File "/Users/k0michi/Repository/Development/misc/python/exception.py", line 2, in <module>
    raise RuntimeError("Exception 1")
RuntimeError: Exception 1

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/k0michi/Repository/Development/misc/python/exception.py", line 4, in <module>
    raise RuntimeError("Exception 2") from e
RuntimeError: Exception 2

raiseに例外を指定しなかった場合は、捕捉中の例外がそのままreraiseされる。

try:
  raise RuntimeError("Exception 1")
except RuntimeError as e:
  raise
Traceback (most recent call last):
  File "/Users/k0michi/Repository/Development/misc/python/exception.py", line 2, in <module>
    raise RuntimeError("Exception 1")
RuntimeError: Exception 1

捕捉中の例外が存在しない場合は以下のような例外になる。

Traceback (most recent call last):
  File "/Users/k0michi/Repository/Development/misc/python/exception.py", line 1, in <module>
    raise
RuntimeError: No active exception to reraise

except

exceptに例外の型を指定すると、その型の例外がtryで投げられた時にのみ実行される。

try:
  open("nonexistent_file")
except RuntimeError:
  print("RuntimeError was thrown")
except FileNotFoundError:
  print("FileNotFoundError was thrown")

型を列挙したタプルを指定することもできる。

try:
  open("nonexistent_file")
except (RuntimeError, FileNotFoundError):
  print("Error occurred")

asで変数を指定すると、その変数で例外インスタンスにアクセスすることができる。

try:
  open("nonexistent_file")
except FileNotFoundError as e:
  print(e.filename)

exceptに何も型を指定しない場合は、任意の型の例外を捕捉する。このexcept節は最後に記述しなければならない。

try:
  raise RuntimeError
except FileNotFoundError as e:
  print(e.filename)
except:
  print("Unknown error occurred")

finally

例外の発生に関わらず、最後に実行される。

try:
  a = open("file")
  raise RuntimeError
except RuntimeError:
  print("RuntimeError")
finally:
  a.close()
  print("File closed")

else

例外が発生しなかった場合に実行される。

try:
  pass
except RuntimeError:
  print("RuntimeError")
else:
  print("else")