У меня есть ситуация, когда я хочу сделать несколько вещей при обработке исключения. Поскольку я хочу рассказать об общем случае, я переведу свой конкретный случай на более общий язык.
Когда у меня есть исключение в этом куске кода, я хочу:
- Всегда выполнять операцию в стиле отката
- Если это
исключение для конкретного приложения, я хочу выполнить регистрацию и проглотить исключение.
Так что я могу придумать два пути решения проблемы, оба безобразно:
# Method nested-try/except block
try:
try:
do_things()
except:
rollback()
raise
except SpecificException as err:
do_advanced_logging(err)
return
# Method Duplicate Code
try:
do_things()
except SpecificException as err:
rollback()
do_advanced_logging(err)
return
except:
rollback()
raise
Оба будут иметь одинаковое поведение.
Я сам склоняюсь к вложенной попытке / кроме решения. Хотя это может быть немного медленнее, я не думаю, что разница в скорости здесь уместна - по крайней мере, не для моего конкретного случая. Дублирование кода - это то, чего я хочу избежать, потому что мой оператор rollback () несколько более сложен, чем просто откат базы данных, даже если он имеет точно такую же цель (он включает веб-API).
Есть третий вариант, который я не заметил, который лучше? Или метод дублированного кода лучше? Обратите внимание, что функциональность rollback () уже разобрана в максимально возможной степени, но все еще содержит вызов функции и три аргумента, которые включают одну жестко закодированную строку. Поскольку эта строка уникальна, нет причин делать ее именованной константой.