Pythonのraise
とraise from
の違いは何ですか?
try:
raise ValueError
except Exception as e:
raise IndexError
をもたらす
Traceback (most recent call last):
File "tmp.py", line 2, in <module>
raise ValueError
ValueError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "tmp.py", line 4, in <module>
raise IndexError
IndexError
そして
try:
raise ValueError
except Exception as e:
raise IndexError from e
をもたらす
Traceback (most recent call last):
File "tmp.py", line 2, in <module>
raise ValueError
ValueError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "tmp.py", line 4, in <module>
raise IndexError from e
IndexError
違いは、from
を使用すると、__cause__
属性が設定され、メッセージには例外がによって直接引き起こされます。 from
を省略すると、__cause__
は設定されませんが、__context__
属性も設定できます、その後、トレースバックは、何かが起こったときの処理中にコンテキストをとして表示します。
例外ハンドラーでraise
を使用した場合、__context__
が設定されます。 raise
を他の場所で使用した場合、__context__
も設定されません。
__cause__
が設定されている場合、__suppress_context__ = True
フラグも例外に設定されます。 __suppress_context__
がTrue
に設定されている場合、トレースバックの印刷時に__context__
は無視されます。
コンテキストを表示したくないしない例外ハンドラーから発生する場合(中に別の例外が発生したメッセージ)、raise ... from None
を使用して__suppress_context__
をTrue
に設定します。
言い換えると、Pythonは例外にcontextを設定するので、例外が発生した場所を内省して、別の例外を確認できます。それに置き換えられました。また、例外にcauseを追加して、他の例外について明示的にトレースバックを作成し(異なる表現を使用)、コンテキストを無視することもできます(ただし、デバッグ時にも内省されます)。 raise ... from None
を使用すると、印刷されるコンテキストを抑制できます。
raise
ステートメントのドキュメント を参照してください:
from
句は、例外チェーンに使用されます。指定する場合、2番目のexpressionは別の例外クラスまたはインスタンスである必要があります。__cause__
属性(書き込み可能)として発生した例外発生した例外が処理されない場合、両方の例外が出力されます:>>> try: ... print(1 / 0) ... except Exception as exc: ... raise RuntimeError("Something bad happened") from exc ... Traceback (most recent call last): File "<stdin>", line 2, in <module> ZeroDivisionError: int division or modulo by zero The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<stdin>", line 4, in <module> RuntimeError: Something bad happened
例外が例外ハンドラーまたは
finally
句内で発生した場合、同様のメカニズムが暗黙的に機能します。前の例外は、新しい例外の__context__
属性として付加されます。>>> try: ... print(1 / 0) ... except: ... raise RuntimeError("Something bad happened") ... Traceback (most recent call last): File "<stdin>", line 2, in <module> ZeroDivisionError: int division or modulo by zero During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 4, in <module> RuntimeError: Something bad happened
コンテキストの詳細と例外に付随する原因情報については、 組み込み例外ドキュメント も参照してください。