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
ベストアンサー1
違いは、 を使用するとfrom
、__cause__
属性が設定され、例外がによって直接発生したことがメッセージに記述されることです。 を省略するとfrom
、 は__cause__
設定されませんが、__context__
属性も設定され、トレースバックには、 の処理中に何か他のことが発生したというコンテキストが表示されます。
例外ハンドラで を__context__
使用した場合に が設定され、他の場所でを使用した場合にも は設定されません。raise
raise
__context__
が設定されている場合__cause__
、__suppress_context__ = True
例外にフラグも設定されます。 が__suppress_context__
に設定されている場合True
、__context__
トレースバックを出力するときに は無視されます。
コンテキストを表示したくない例外ハンドラーから発生させる場合(処理中に別の例外が発生したというメッセージを表示したくない場合)、 を使用しraise ... from None
て に設定し__suppress_context__
ますTrue
。
言い換えると、Python は例外にコンテキストを設定するので、例外が発生した場所を内部調査して、別の例外がその例外に置き換えられたかどうかを確認できます。例外に原因を追加して、トレースバックで他の例外を明示的に表示することもできます (別の言い回しを使用)。コンテキストは無視されます (ただし、デバッグ時に内部調査することはできます)。を使用すると、raise ... from None
コンテキストが印刷されるのを抑制できます。
を参照してくださいraise
声明文書:
この
from
句は例外の連鎖に使用されます。指定されている場合、2 番目の式は別の例外クラスまたはインスタンスである必要があり、発生した例外に属性 (書き込み可能) として添付されます__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
以下も参照組み込み例外ドキュメント例外に付随するコンテキストと原因情報の詳細。