2016-02-29 2 views
3

Если я не уверен в чем-то при написании кода, я еще раз хочу прочитать The Zen of Python. На этот раз эти линии меня мешают.Что такое предпочтительный способ обработки исключений?

Errors should never pass silently. 
Unless explicitly silenced. 

В текущем коде у меня есть некоторые функции, которые могли бы выглядеть следующим образом:

def add_v_1(a, b): 
    return a + b 

И все звонки для них, как:

c = add_v_1(7, []) 

Исключение такого кода будет пузыриться и пойманных на верхних слоях.

Но должно ли это быть так?

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

try: 
    c = add_v_1(7, []) 
except TypeError: 
    print "Incorrect types!" 

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

Итак, я могу сделать:

def add_v_2(a, b): 
    try: 
     return a + b 
    except TypeError: 
     print "Incorrect types!" 

и вызов будет:

c = add_v_2(7, []) 

, который выглядит чище.

Кажется, все эти подходы следуют The Zen of Python, но какой из них лучший выбор?

+1

Я бы сказал, это зависит, в вашем случае, если вы обработать исключение внутри функции вы все равно должны будете обращаться он тоже снаружи, потому что он вернет None. – Hacketo

+0

@Hacketo Что вы будете делать с текущим примером? –

ответ

3

Со ссылкой на ваш пример, это спорно, следует ли вы поймать исключение внутри функции. Это приведет к возврату None из функции, которая затем обременяет вызывающий код с проверкой возвращаемого значения функции и обрабатывает None как ошибку. Он эффективно заменяет обработку исключений при проверке ошибок. Первый, как правило, более Pythonic.

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

И что вы можете сделать, чтобы справиться с такой ошибкой? Кажется, что нет никакого полезного значения, которое могло бы быть возвращено в домене ожидаемого выхода функции ... кроме None, чтобы сообщить, что результат не может быть получен. Но вызывающий код по-прежнему должен выполнить некоторую проверку ошибок ... поэтому он может просто обработать исключение - по крайней мере, он должен обрабатывать только один раз.

Но пример надуман, и сложно дать советы по одеялу. В этой конкретной ситуации по указанным выше причинам я разрешаю исключение распространяться на вызывающий код и обрабатывать его там.

0

Вход:

def add_v_2(a, b): 
    try: 
     return a + b 
    except Exception as e: 
     print str(e) 
c = add_v_2(7, []) 
print (c) 

Выход:

unsupported operand type(s) for +: 'int' and 'list' 
None 
+0

@viakondratiuk - В вашем коде 2-е место лучше всего, если в любом случае вы будете делать то же самое снова, не нужно использовать try catch еще раз – GThamizh

+2

Я не могу рекомендовать catching 'Exception', это далеко не общий. Вы должны поймать исключения, которые вы ожидаете и можете обрабатывать, в этом случае вы можете поймать 'TypeError'. – mhawke

2

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

Предположим, вы написали класс IntegerWrapper, и ваша функция «add_v_2» должна обычно пытаться объединить два значения.

def add_v_2(a, b): 
    try: 
     return a + b 
    except TypeError as e: 
     if isinstance(a, IntegerWrapper): 
      return str(a) + b 
     else: 
      print("I dont know how to handle this type: " + type(a).__name__) 
      # reraise the error so the caller can handle it 
      raise 

Это будет пытаться восстановить из a бытия «неправильного типа», но если вы знаете, как избавиться от него. Если он не знает (имеет другой тип), он регрессирует исключение, поэтому тот, кто знает, как это можно обработать, видит ошибку.

(Конечно, что реализация содержит ошибки, это не значит быть «хорошая реализация»)

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