Ранний перехват исключений
Анти-паттерн
Исключение ловят не там, где оно возникло, а там где его удобно обработать. Исключение само будет всплывать от функции к функции пока не встретит подходящий обработчик.
Пример 1¶
Плохо:
def divide(num1, num2):
result = None
try:
result = num1 / num2
except ZeroDivisionError as e:
logging.error(f'ZeroDivisionError: {e}')
finally:
return result
def main():
num1 = 1
num2 = 0
result = divide(num1, num2)
print(result)
Хорошо:
def divide(num1, num2):
result = num1 / num2
return result
def main():
num1 = ...
num2 = ...
try:
result = divide(num1, num2)
except ZeroDivisionError as e:
logging.error(f'ZeroDivisionError: {e}')
finally:
print result
Пример 2¶
Функция, которая поднимает исключение, должна только сигнализировать об ошибке, а не решать, как с ней поступать.
Плохо:
class EmptyLessonError(Exception):
pass
def validate_lesson(raw_lesson):
try:
if raw_lesson == '':
raise EmptyLessonError('Урок не содержит материалов!')
...
except EmptyLessonError as e:
logging.warning(f'EmptyLessonError: {e}')
except ...
...
def main():
raw_lesson = ...
lesson = validate_lesson(raw_lesson)
...
Хорошо:
class EmptyLessonError(Exception):
pass
def validate_lesson(raw_lesson):
if raw_lesson == '':
raise EmptyLessonError('Урок не содержит материалов!')
...
def main():
raw_lesson = ...
try:
lesson = validate_lesson(raw_lesson)
except EmptyLessonError as e:
logging.warning(f'EmptyLessonError: {e}')
except ...