Исключения являются мощными, но одно чрезмерное усердие, за исключением предложения, может убрать все это в одну строку.
try:
res = get_result()
res = res[0]
log('got result: %r' % res)
except:
if not res:
res = ''
print('got exception')
Этот пример демонстрирует 3 симптома антипаттерна:
- За
except
без указания типа исключения (строка 5) будет ловить даже здоровые исключения, в том числеKeyboardInterrupt
. Это предотвратит выход из программы в некоторых случаях. - Кроме блока не ререйз ошибки, а это означает , что мы не сможем сказать , если исключение пришло в
get_result
или потому , чтоres
был пустой список. - Хуже всего то, что если мы беспокоились о том, что результат окажется пустым, мы стали причиной чего-то гораздо худшего. Если
get_result
не удается,res
будет оставаться полностью снято с охраной, а также ссылка наres
в блоке , за исключением, подниметNameError
, полностью маскирует первоначальную ошибку.
Всегда думайте о типе исключения, которое вы пытаетесь обработать. Дайте странице Исключения для чтения и получить ощущение того, что существуют основные исключения.
Вот исправленная версия примера выше:
import traceback
try:
res = get_result()
except Exception:
log_exception(traceback.format_exc())
raise
try:
res = res[0]
except IndexError:
res = ''
log('got result: %r' % res)
Мы ловим более конкретные исключения, ререйзируем при необходимости. Еще несколько строк, но бесконечно правильнее.