programing tip

중첩 된 try / except 블록에서 예외를 다시 발생시키는 방법은 무엇입니까?

itbloger 2020. 10. 17. 10:03
반응형

중첩 된 try / except 블록에서 예외를 다시 발생시키는 방법은 무엇입니까?


예외를 다시 발생 raise시키려면 각 except블록 에서 인수없이 간단히 사용한다는 것을 알고 있습니다. 그러나 다음과 같은 중첩식이 주어지면

try:
    something()
except SomeError as e:
    try:
        plan_B()
    except AlsoFailsError:
        raise e  # I'd like to raise the SomeError as if plan_B()
                 # didn't raise the AlsoFailsError

SomeError스택 추적을 끊지 않고 어떻게 다시 올릴 수 있습니까? raise이 경우에만 더 최근의 AlsoFailsError. 또는이 문제를 방지하기 위해 코드를 리팩터링하려면 어떻게해야합니까?


예외 유형, 값 및 역 추적을 지역 변수에 저장하고 다음의 세 인수 형식을 사용할 수 있습니다raise .

try:
    something()
except SomeError:
    t, v, tb = sys.exc_info()
    try:
        plan_B()
    except AlsoFailsError:
        raise t, v, tb

Python 3에서는 트레이스 백이 예외에 저장되므로 raise e(대부분) 올바른 작업을 수행합니다.

try:
    something()
except SomeError as e:
    try:
        plan_B()
    except AlsoFailsError:
        raise e

위의 유일한 문제는 SomeError처리하는 동안 AlsoFailsError( raise einside 때문에) 발생 했음을 알려주는 약간 오해의 소지가있는 트레이스 백을 생성한다는 것입니다 except AlsoFailsError. 실제로는 거의 정반대가 발생했습니다 . AlsoFailsError에서 복구하는 동안 처리했습니다 SomeError. 이 동작을 비활성화 언급하지 역 추적을 얻으려면 AlsoFailsError, 교체 raise e와 함께 raise e from None.


허용되는 솔루션 이 맞 더라도 .NET Framework를 사용하여 Python 2 + 3 솔루션이있는 Six 라이브러리 를 가리키는 것이 좋습니다 six.reraise.

육. 리 레이즈 ( exc_type , exc_value , exc_traceback = 없음)

다른 트레이스 백을 사용하여 예외를 다시 발생시킵니다. [...]

따라서 다음과 같이 작성할 수 있습니다.

import six


try:
    something()
except SomeError:
    t, v, tb = sys.exc_info()
    try:
        plan_B()
    except AlsoFailsError:
        six.reraise(t, v, tb)

드류 McGowen의 제안 하지만, (반환 값은 일반적인 경우를 돌보는 s존재), 여기에 대한 대안의 user4815162342의 대답은 :

try:
    s = something()
except SomeError as e:
    def wrapped_plan_B():
        try:
            return False, plan_B()
        except:
            return True, None
    failed, s = wrapped_plan_B()
    if failed:
        raise

Python 3.5+는 어쨌든 트레이스 백 정보를 오류에 첨부하므로 더 이상 별도로 저장할 필요가 없습니다.

>>> def f():
...   try:
...     raise SyntaxError
...   except Exception as e:
...     err = e
...     try:
...       raise AttributeError
...     except Exception as e1:
...       raise err from None
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in f
  File "<stdin>", line 3, in f
SyntaxError: None
>>> 

참고 URL : https://stackoverflow.com/questions/18188563/how-to-re-raise-an-exception-in-nested-try-except-blocks

반응형