Program Tip

파이썬 예외 체이닝

programtip 2020. 10. 24. 11:40
반응형

파이썬 예외 체이닝


이 질문에 이미 답변이 있습니다.

Python에서 예외 체인을 사용하는 표준 방법이 있습니까? Java 예외 '원인'처럼?

여기에 몇 가지 배경이 있습니다.

하나의 주요 예외 클래스가있는 모듈이 있습니다 DSError.

 class DSError(Exception):
     pass

이 모듈의 어딘가에는 다음이 있습니다.

try:
    v = my_dict[k]
    something(v)
except KeyError as e:
    raise DSError("no key %s found for %s" % (k, self))
except ValueError as e:
    raise DSError("Bad Value %s found for %s" % (v, self))
except DSError as e:
    raise DSError("%s raised in %s" % (e, self))

기본적으로이 스 니펫은 DSError 만 던져야하며 무슨 일이 일어 났는지, 왜 그런지 알려 주어야합니다. 문제는 try 블록이 다른 많은 예외를 throw 할 수 있으므로 다음과 같은 작업을 수행 할 수 있으면 선호합니다.

try:
    v = my_dict[k]
    something(v)
except Exception as e:
    raise DSError(self, v, e)  # Exception chained...

이 표준 비단뱀 방식입니까? 다른 모듈에서 예외 체인을 보지 못했는데 파이썬에서 어떻게 수행됩니까?


예외 체이닝 은 Python 3에서만 사용할 수 있으며 다음과 같이 작성할 수 있습니다.

try:
    v = {}['a']
except KeyError as e:
    raise ValueError('failed') from e

다음과 같은 출력을 산출합니다.

Traceback (most recent call last):
  File "t.py", line 2, in <module>
    v = {}['a']
KeyError: 'a'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "t.py", line 4, in <module>
    raise ValueError('failed') from e
ValueError: failed

대부분의 경우에는 from; Python 3은 기본적으로 다음과 같이 예외 처리 중에 발생한 모든 예외를 표시합니다.

Traceback (most recent call last):
  File "t.py", line 2, in <module>
    v = {}['a']
KeyError: 'a'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "t.py", line 4, in <module>
    raise ValueError('failed')
ValueError: failed

Python 2 에서 할 수있는 작업은 다음과 같이 예외 클래스에 사용자 지정 속성을 추가하는 것입니다.

class MyError(Exception):
    def __init__(self, message, cause):
        super(MyError, self).__init__(message + u', caused by ' + repr(cause))
        self.cause = cause

try:
    v = {}['a']
except KeyError as e:
    raise MyError('failed', e)

이것이 당신이 요구하는 것입니까?

class MyError(Exception):
    def __init__(self, other):
        super(MyError, self).__init__(other.message)

>>> try:
...     1/0
... except Exception, e:
...     raise MyError(e)
Traceback (most recent call last):
  File "<pyshell#27>", line 4, in <module>
    raise MyError(e)
MyError: division by zero

원래 예외 객체를 저장하려면 확실히 자신의 예외 클래스의 __init__. 예외 객체 자체가 예외가 발생한 위치에 대한 유용한 정보를 제공하지 않기 때문에 실제로 트레이스 백을 저장하고 싶을 수 있습니다.

class MyError(Exception):
    def __init__(self, other):
        self.traceback = sys.exc_info()
        super(MyError, self).__init__(other.message)

그런 다음 traceback예외 속성에 액세스 하여 원래 예외에 대한 정보를 얻을 수 있습니다. (Python 3은 이미 __traceback__예외 객체 속성으로이를 제공 합니다.)

참고URL : https://stackoverflow.com/questions/16414744/python-exception-chaining

반응형