“Внутреннее исключение” (с traceback) в Python?

Вы полагаете [1,2] пересекаться с [1, [2]]? Таким образом, действительно ли это - только числа, о которых Вы заботитесь о, или структура списка также?

, Если только числа, займитесь расследованиями, как "сгладить" списки, то используйте set() метод.

131
задан EMP 31 August 2009 в 00:16
поделиться

4 ответа

Python 2

Это просто; передать трассировку в качестве третьего аргумента для поднятия.

import sys
class MyException(Exception): pass

try:
    raise TypeError("test")
except TypeError, e:
    raise MyException(), None, sys.exc_info()[2]

Всегда делайте это при перехвате одного исключения и повторном вызове другого.

132
ответ дан 24 November 2019 в 00:14
поделиться

В Python 3.x :

raise Exception('Failed to process file ' + filePath).with_traceback(e.__traceback__)

или просто

except Exception:
    raise MyException()

, который будет распространять MyException , но печатать оба исключения, если оно не будет обработано.

В Python 2.x :

raise Exception, 'Failed to process file ' + filePath, e

Вы можете предотвратить печать обоих исключений, убрав атрибут __ context __ . (см. http://docs.python.org/3.1/library/stdtypes.html для более подробного описания того, как они работают)

try: # Wrap the whole program into the block that will kill __context__.

    class Catcher(Exception):
        '''This context manager reraises an exception under a different name.'''

        def __init__(self, name):
            super().__init__('Failed to process code in {!r}'.format(name))

        def __enter__(self):
            return self

        def __exit__(self, exc_type, exc_val, exc_tb):
            if exc_type is not None:
                self.__traceback__ = exc_tb
                raise self

    ...


    with Catcher('class definition'):
        class a:
            def spam(self):
                # not really pass, but you get the idea
                pass

            lut = [1,
                   3,
                   17,
                   [12,34],
                   5,
                   _spam]


        assert a().lut[-1] == a.spam

    ...


except Catcher as e:
    e.__context__ = None
    raise
11
ответ дан 24 November 2019 в 00:14
поделиться

Я не думаю, что вы можете сделать это в Python 2.x, но что-то похожее на эту функциональность есть часть Python 3. Из PEP 3134 :

В сегодняшней реализации Python исключения состоят из трех части: тип, значение и трассировка. Модуль 'sys', представляет текущее исключение в трех параллельных переменных, exc_type, exc_value и exc_traceback функция sys.exc_info () возвращает кортеж из этих трех частей, а оператор повышения имеет форма с тремя аргументами, принимающая эти три части. Манипулирование исключения часто требуют параллельной передачи этих трех вещей, что может быть утомительным и подверженным ошибкам. Кроме того, "за исключением" оператор может предоставить доступ только к значению, но не к трассировке. Добавление атрибута « traceback » к значениям исключения делает все информация об исключении доступна из единого места.

Сравнение с C #:

Исключения в C # содержат свойство InnerException только для чтения, которое может указывать на другое исключение. В его документации [10] говорится, что "Когда исключение X выбрасывается как прямой результат предыдущего исключение Y, свойство InnerException X должно содержать ссылка на Y. "Это свойство не устанавливается виртуальной машиной автоматически; скорее, все конструкторы исключений принимают необязательное внутреннее исключение аргумент, чтобы установить его явно. Атрибут " причина " выполняет та же цель, что и InnerException, но этот PEP предлагает новую форму 'поднять', а не расширять конструкторы всех исключений. C # также предоставляет метод GetBaseException, который переходит непосредственно к конец цепочки InnerException; этот PEP не предлагает аналогов.

Обратите внимание, что Java, Ruby и Perl 5 также не поддерживают этот тип вещей. Еще раз процитируем:

Что касается других языков, Java и Ruby отвергают оригинал. исключение, когда другое исключение возникает в 'catch' / 'rescue' или Предложение 'finally' / 'sure'. Perl 5 не имеет встроенной структурированной Обработка исключений. Для Perl 6 RFC номер 88 [9] предлагает исключение. механизм, который неявно сохраняет связанные исключения в массиве с именем @@.

5
ответ дан 24 November 2019 в 00:14
поделиться

Может быть, вы могли бы взять соответствующую информацию и передать ее? Я думаю примерно так:

import traceback
import sys
import StringIO

class ApplicationError:
    def __init__(self, value, e):
        s = StringIO.StringIO()
        traceback.print_exc(file=s)
        self.value = (value, s.getvalue())

    def __str__(self):
        return repr(self.value)

try:
    try:
        a = 1/0
    except Exception, e:
        raise ApplicationError("Failed to process file", e)
except Exception, e:
    print e
2
ответ дан 24 November 2019 в 00:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: