Обработка исключения Python, которое встречается в предложении except

У меня есть код в предложении Python except, который предназначен для выполнения некоторых протоколирования, но сам журнал может вызвать исключение. В моем случае я хотел бы просто игнорировать любое второе исключение, которое могло бы произойти, и поднять исходное исключение. Вот очень упрощенный пример:

try:
    a = this_variable_doesnt_exist
except:
    try:
        1/0
    except:
        pass
    raise

Запустив вышеуказанный код, я надеюсь получить:

NameError: name 'this_variable_doesnt_exist' is not defined

но вместо этого, в Python 2.x, я получаю:

ZeroDivisionError: integer division or modulo by zero

Я обнаружил, что в Python 3.x он делает то, что я хочу.

Я не мог найти много комментариев по этому поводу в документах Python 2.x(если только не пропустил это). Могу ли я достичь этого в 2.x?

Ответ 1

С абстракцией:

def log_it():
    try:
        1 / 0
    except:
        pass

try:
    this = that
except:
    log_it()
    raise

Что вы хотите в Python 2.5

Другой способ сделать это - сохранить исключение в переменной, а затем повторно установить его явно:

try:
    this = that
except NameError, e: # or NameError as e for Python 2.6
    try:
        1 / 0
    except:
        pass
    raise e

Обратите внимание, что вы, вероятно, не должны просто использовать голый except, чтобы поймать все, что могло бы произойти - обычно лучше всего поймать определенные исключения, которые вы ожидаете, в случае резкого и фатального исключения (например, из-за нехватки памяти).

Ответ 2

Я считаю, что то, что вы видите, является результатом цепочки исключений, которая является изменение в Python 3.

Из раздела Мотивация PEP:

Во время обработки одного исключения (исключение A) возможно, что может произойти другое исключение (исключение B). В настоящее время Python (версия 2.4), если это происходит, исключение B распространяется наружу, а исключение A теряется. Чтобы отладить проблему, полезно знать обо всех исключениях. Атрибут __context__ сохраняет эту информацию автоматически.

Далее PEP описывает подробное описание новой цепочки исключений (которая реализована в Py3k), это интересное чтение. Сегодня я узнал что-то новое.

Ответ 3

В моем классе CausedException я позабочусь об этом для Python 2.x(а также для Python 3, если вы хотите пройти вызывают деревья вместо простых цепочек причин). Может быть, это может вам помочь.