Цепочка исключений Python [дубликат]
этот вопрос уже есть ответ здесь:
"Внутреннее исключение" (с трассировкой) в Python?
8 ответов
существует ли стандартный способ использования цепочек исключений в 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 может бросить много других исключений, поэтому я предпочел бы, если я могу сделать что-то вроде:
try:
v = my_dict[k]
something(v)
except Exception as e:
raise DSError(self, v, e) # Exception chained...
это стандарт для Python способ? Я не видел цепочек исключений в других модулях, так как это делается в Python?
2 ответов:
исключения-цепочки доступно только в 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__атрибут объекта исключения.)
Comments