Использование "кроме исключения" против "кроме... повышения" в Python
Я читаю некоторый исходный код, который содержит функцию, подобную следующей:
def dummy_function():
try:
g = 1/0
except Exception as e:
raise Exception("There is an error: {}".format(e))
Насколько я понимаю, все исключения являются производными от класса Exception, поэтому это должно отлавливать все ошибки. После https://docs.python.org/3/tutorial/errors.html это не будет эквивалентно
def dummy_function():
try:
g = 1/0
except:
print "There is an error:"
raise
Я замечаю, что в обоих случаях распечатка выводится немного по-разному, но мне кажется, что второй метод в основном тот же и менее многословный. Или я что-то упустил?
1 ответ
Нет, ваш код не эквивалентен по нескольким причинам:
- Пустой
except:
ловит все исключения, в том числе полученные изBaseException
(SystemExit
,KeyboardInterrupt
а такжеGeneratorExit
); привлекательныйException
отфильтровывает те исключения, которые вы обычно хотите избежать без повторного повышения. В старых выпусках Python он также ловил исключения строк (больше не разрешается). -
except Exception as e
ловит подклассы, но потом поднимает новыйException()
пример; информация о конкретном типе больше не может использоваться в нисходящем направленииtry...except
заявления. - В Python 3 поднятие нового исключения из обработчика исключений создает цепочку исключений (где исходное исключение добавляется как
Exception.__context__
атрибут, см. использование Python "повышение от") - Сообщение обновлено; в этом, пожалуй, и весь смысл в том, чтобы дать исключению другое сообщение.
Код, который вы нашли... довольно плохая практика. Обработчик исключений верхнего уровня должен просто перехватить и напечатать сообщение и, возможно, трассировку, а не повторно вызывать исключение с новым сообщением (и в Python 2 потерять всю информацию об исходном исключении, в Python 3 сделать его недоступным для исключения соответствие в более поздних обработчиках).