Я не согласен с ключевым предложением в существующих ответах, которое в основном сводится к обработке исключений в Python, как, скажем, в C ++ или Java - это НЕ предпочтительный стиль в Python, где часто бывают старые добрые идеи, которые «лучше просить прощения, чем разрешения» (попытайтесь выполнить операцию и разберитесь с исключением, если оно есть, вместо того, чтобы затенять основной поток кода и нести накладные расходы путем тщательных предварительных проверок). Я согласен с Габриэлем в том, что голая except
вряд ли когда-либо будет хорошей идеей (если все, что она делает, это какая-то форма регистрации, за которой следует raise
, чтобы позволить распространению исключения). Итак, скажем, у вас есть кортеж со всеми типами исключений, которые вы ожидаете и хотите обрабатывать одинаково, скажем:
expected_exceptions = KeyError, AttributeError, TypeError
и всегда используйте except expected_exceptions:
, а не голый except:
.
Итак, с учетом этого, один немного менее повторяющийся подход к вашим потребностям:
try:
foo1()
except expected_exceptions:
try:
if condition:
foobetter()
else:
raise
except expected_exceptions:
handleError()
Другой подход заключается в использовании вспомогательной функции для переноса логики try / кроме:
def may_raise(expected_exceptions, somefunction, *a, **k):
try:
return False, somefunction(*a, **k)
except expected_exceptions:
return True, None
Такой помощник часто может оказаться полезным в нескольких различных ситуациях, поэтому довольно часто иметь что-то подобное где-то в «служебных» модулях проекта. Теперь для вашего случая (без аргументов, без результатов) вы можете использовать:
failed, _ = may_raise(expected_exceptions, foo1)
if failed and condition:
failed, _ = may_raise(expected_exceptions, foobetter)
if failed:
handleError()
Я бы сказал, что он более линейный и, следовательно, более простой. Единственная проблема этого общего подхода заключается в том, что вспомогательная функция, такая как may_raise
, не заставляет вас так или иначе иметь дело с исключениями, поэтому вы могли бы просто забыть это сделать (так же, как и использование кодов возврата вместо исключений, указывающих на ошибки, склонен к ошибочным игнорированию этих возвращаемых значений); так что используйте его экономно ...! -)