web-dev-qa-db-ja.com

再スローpython例外。どちらをキャッチしますか?

私はpythonを使用することを学んでいます。私はちょうどこの記事に出会いました: http://nedbatchelder.com/blog/200711/rethrowing_exceptions_in_python.html このように、Pythonでの例外の再スローについて説明します。

try:
    do_something_dangerous()
except:
    do_something_to_apologize()
    raise

例外を再スローするため、「外側のcatch-except」ステートメントがあるはずです。しかし、今、私は考えていました。 except内のdo_something_to_apologize()がエラーをスローした場合はどうなりますか。どちらが外側の「catch-except」でキャッチされますか?あなたが再スローするもの、またはdo_something_to_apologize()によってスローされるもの?または、最高の優先順位を持つ例外が最初にキャッチされますか?

25
Bosiwow

試してみてください:

def failure():
    raise ValueError, "Real error"

def apologize():
    raise TypeError, "Apology error"

try:
    failure()
except ValueError:
    apologize()
    raise

結果:

Traceback (most recent call last):
  File "<pyshell#14>", line 10, in <module>
    apologize()
  File "<pyshell#14>", line 5, in apologize
    raise TypeError, "Apology error"
TypeError: Apology error

理由:元の関数からの「実際の」エラーは、exceptによってすでにキャッチされていました。 apologizeは新しいエラーを発生させますraiseに達する前。したがって、raise句のexceptは実行されず、謝罪のエラーのみが上方に伝播します。 apologizeでエラーが発生した場合、Pythonには、apologizeの後に別の例外が発生することを知る方法がありません。

Python 3)では、トレースバックはboth例外に言及し、2番目の例外がどのように発生したかを説明するメッセージに注意してください。

Traceback (most recent call last):
  File "./prog.py", line 9, in <module>
  File "./prog.py", line 2, in failure
ValueError: Real error

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./prog.py", line 11, in <module>
  File "./prog.py", line 5, in apologize
TypeError: Apology error

ただし、2番目の例外(「謝罪」例外)は、依然として外側に伝播し、より高いレベルのexcept句でキャッチできる唯一の例外です。元の例外はトレースバックに記載されていますが、後の例外に含まれているため、キャッチできません。

48
BrenBarn

Do_something_to_apologize()によってスローされた例外がキャッチされます。 do_something_to_apologizeによってスローされる例外のため、raiseを含む行は実行されません。また、python exceptions。に「優先順位」という考えがあるとは思わない。

7
ibebrett