2016-10-25 2 views
3

Допустим, мы имеем следующий код:Правильная степень блока обработки исключений

print("...") 
might_throw_type_error() 
print("...") 
might_throw_index_error() 

Если мы хотим, чтобы обрабатывать исключения, что эти функции могут возникнуть, что является предпочтительным способом:


Полное разделение "бизнес" и код обработки ошибок

try: 
    print("...") 
    might_throw_type_error() 
    print("...") 
    might_throw_index_error() 
except IndexError: 
    # index error handling logic 
    raise 
except TypeError: 
    # index error handling logic 
    raise 

Разделение логики и обработки ошибок, но попробовать, начиная с первого оператора, который может поднять

print("...") 
try: 
    might_throw_type_error() 
    print("...") 
    might_throw_index_error() 
except IndexError: 
    # index error handling logic 
    raise 
except TypeError: 
    # index error handling logic 
    raise 

Обработка исключений следует обернуть только заявления, которые мы ожидаем, чтобы поднять

print("...") 
try: 
    might_throw_type_error() 
except TypeError: 
    # index error handling logic 
    raise 
print("...") 
try: 
    might_throw_index_error() 
except IndexError: 
    # index error handling logic 
    raise 

Обратите внимание, что если мы зафиксируем исключение, которое мы не хотим продолжать

+1

Это довольно основанный на мнениях ... [codereview.se] может быть лучше подходит для таких вопросов. –

+0

Счастливый, чтобы переместить его, задавая в случае, если есть «пифонический» ответ: $ –

+0

На самом деле это не вопрос Пифонов, а вкуса. CodeReview, вероятно, скажет то же самое. – msw

ответ

2

Это de конечно, зависит от , что именно вы хотите достичь - считают, что если вы будете использовать # 1 подход, если что-то пойдет не так с первым might_throw_index_error следующий print и второй might_throw_index_errorникогда не была выполнена.

С другой стороны, последний гарантирует, что по крайней мере secon print всегда будет стрелять.

Каждый из этих способов хорош, но зависит от того, что вы хотите делать с потоком приложения.

+0

извините, забыли добавить это. обработка исключений - только журналы и ререйз (так логика такая же).Позвольте мне уточнить вопрос –

+0

Ответ все тот же - важно только, если вы хотите попробовать запустить второй метод в случае сбоя на первом - если нет, то нет причин не помещать их внутри одного 'try-except' –

+0

. Итак, вы не согласны с предложением «Обработка исключений должна только обертывать заявления, которые мы ожидаем поднять». Аргумент для этого заключался в том, что для читателя становится понятнее, какая функция вызывает конкретный тип исключения. –

-1

Создайте декоратор и добавьте этот декоратор в каждое определение вашей функции. Для получения подробной информации см. A guide to Python's function decorators. Например, ваш декоратор должен быть как:

def wrap_error(func): 
    def func_wrapper(*args, **kwargs): 
     try: 
      return func(*args, **kwargs) 
     except ValueError: 
      # Some logic here 
     except IndexError: 
      # some logic here 
    return func_wrapper 

Теперь добавьте этот декоратор с определением функции, как:

@wrap_error 
def function1(): 
    some code 

Теперь вы можете просто сделать вызов функции, как:

function1() # No need to handle the errors explicitly 

, не беспокоясь о явной обработке ошибок при каждом вызове.

+0

«Явное лучше, чем неявное», и исключение обертывания в декораторе столь же пугающе неявное, как я видел. – msw

+0

Зависит от требований к требованию. Мой взгляд на это немного отличается. По мне это лучше. Предположим, вы хотите записать записи в файл журнала. Позже требование изменилось, и теперь вам также нужно отправить электронное письмо. Пойдете ли вы и измените код каждый раз, когда будете обрабатывать исключение? Это обеспечивает более чистый способ. Ваш код функции изолирован от неприятного try/except, ваша основная функция чиста, а декоратор сидит в углу, управляя всеми неприятными задачами –

Смежные вопросы