raise
このページでは豊富な例を用いてPythonのraise文の使い方を学ぶことができます。
raise文は任意の例外をコードの中で発生させることができます。
raise文には例外クラス・インスタンス(BaseException、もしくはその派生クラス・インスタンス)を指定します。 指定しない場合は、実行しているスコープで最終的に有効な例外を再送出します。
# 記述例
raise 例外クラス・インスタンス
TL;DR
基本
# 意図的に例外を発生させることができる
raise Exception
------------------------------
Traceback (most recent call last):
...
Exception
------------------------------
# 引数あり
raise RuntimeError('An intentionally occurred Error.')
------------------------------
Traceback (most recent call last):
...
RuntimeError: An intentionally occurred Error.
------------------------------
# BaseException、またはその派生クラスでないと指定できない
raise int
------------------------------
Traceback (most recent call last):
...
TypeError: exceptions must derive from BaseException
------------------------------
# BaseExceptionを継承した例外クラス
class MyError(BaseException):
pass
raise MyError
------------------------------
Traceback (most recent call last):
...
__main__.MyError
------------------------------
# 例外が発生していない状況でraise文に何も指定しない場合
raise
------------------------------
Traceback (most recent call last):
...
RuntimeError: No active exception to reraise
------------------------------
関連情報:class(クラス定義)の使用方法
例外の再送出
# 例外を再送出しない場合
try:
int('python')
except ValueError:
print('EXCEPT process')
print('FooBarNinja')
==> EXCEPT process
==> FooBarNinja
# 例外を再送出する場合
try:
int('python')
except ValueError:
print('EXCEPT process')
raise
print('FooBarNinja')
------------------------------
EXCEPT process
Traceback (most recent call last):
...
ValueError: invalid literal for int() with base 10: 'python'
------------------------------
関連情報:例外処理(try,except,else,finally)の使用方法
例外の連鎖
# 例外を連鎖させない場合
try:
int('python')
except ValueError:
raise Exception
------------------------------
Traceback (most recent call last):
...
ValueError: invalid literal for int() with base 10: 'python'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
...
Exception
------------------------------
# 例外を連鎖させる場合
try:
int('python')
except ValueError as err:
# fromを指定する
raise Exception from err
------------------------------
Traceback (most recent call last):
...
ValueError: invalid literal for int() with base 10: 'python'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
...
Exception
------------------------------
# Noneを指定すると例外の連鎖を明示的に非表示にできる
try:
int('python')
except ValueError as err:
# fromを指定する
raise Exception from None
------------------------------
Traceback (most recent call last):
...
Exception
------------------------------
解説
# 記述例
raise 例外クラス・インスタンス
基本
raise文は例外クラスもしくはそのインスタンスを指定することで、任意の場所で例外を発生させることができます。 例外インスタンスではなくクラスを指定した場合、暗黙的に引数なしのコンストラクタが呼び出されてインスタンス化されます。
raise文に指定する例外クラス・インスタンスとは、BaseException、もしくはBaseExceptionクラスの派生クラス・インスタンスである必要があります。
そうではないクラス・インスタンスを指定した場合、TypeError
が発生します。
raise RuntimeError
------------------------------
Traceback (most recent call last):
...
RuntimeError
------------------------------
# 引数あり
raise Exception('FooBarNinja Test')
------------------------------
Traceback (most recent call last):
...
Exception: FooBarNinja Test
------------------------------
class MyBadExampleError:
pass
# BaseExceptionかその派生クラスでなければならない
raise MyBadExampleError
------------------------------
Traceback (most recent call last):
...
TypeError: exceptions must derive from BaseException
------------------------------
class MyGoodExampleError(BaseException):
pass
# BaseExceptionの派生クラスなのでraise文に指定できる
raise MyGoodExampleError
------------------------------
Traceback (most recent call last):
...
__main__.MyGoodExampleError
------------------------------
# 例外が発生していない状況でraise文に何も指定しない場合
raise
------------------------------
Traceback (most recent call last):
...
RuntimeError: No active exception to reraise
------------------------------
関連情報:class(クラス定義)の使用方法
例外の再送出
raise文は例外クラス・インスタンスを指定しないで使用することもできます。
この場合、「実行されているスコープで最終的に有効になっている例外」を再送出します。
「実行されているスコープで最終的に有効になっている例外」がない場合は、RuntimeError
が発生します。
以下のコード例ではtry文のexcept節内でキャッチしたZeroDivisionError
をraise文で再送出しています。
再送出した場合と、していない場合の挙動を比較してみてください。
# except節で例外を処理
try:
1 / 0
except ZeroDivisionError:
print('EXCEPT process')
print('FooBarNinja')
==> EXCEPT process
==> FooBarNinja
# except節で例外を処理せず再送出
try:
1 / 0
except ZeroDivisionError:
print('EXCEPT process')
raise
print('FooBarNinja')
------------------------------
EXCEPT process
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
------------------------------
関連情報:例外処理(try,except,else,finally)の使用方法
例外の連鎖
from
をraise文とともに使用することで例外を連鎖させることができます。
fromの後ろには連鎖させたい例外を指定します。
また、fromにNone
を指定すると例外の連鎖を無効にすることもできます。
# 例外を連鎖させない場合
try:
1 / 0
except ZeroDivisionError:
raise Exception
------------------------------
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
...
Exception
------------------------------
# 例外を連鎖させる場合
try:
1 / 0
except ZeroDivisionError as err:
raise Exception from err
------------------------------
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
...
Exception
------------------------------
# Noneの指定
try:
1 / 0
except ZeroDivisionError as err:
raise Exception from None
------------------------------
Traceback (most recent call last):
...
Exception
------------------------------