Try/else с возвратом в блоке try
Я столкнулся с странным поведением в python. Я не мог найти информацию об этом в справке python или в SE, так вот:
def divide(x, y):
print 'entering divide'
try:
return x/y
except:
print 'error'
else:
print 'no error'
finally:
print 'exit'
print divide(1, 1)
print divide(1, 0)
вывод:
entering divide
exit
1
entering divide
error
exit
None
Похоже, что python не войдет в блок else
, если значение возвращается в try
. Однако он всегда будет находиться в блоке finally
. Я не понимаю, почему. Может ли кто-нибудь помочь мне с этой логикой?
спасибо
Ответы
Ответ 1
http://docs.python.org/reference/compound_stmts.html#the-try-statement
Необязательное предложение else выполняется, если и когда управление течет конец предложения try.
В настоящее время управление "течет с конца", за исключением случая исключение или выполнение инструкции return, continue или break.
Ответ 2
Причиной такого поведения является return
внутри try
.
Когда возникает исключение, оба finally
и except
блокируют выполнение перед return
. В противном случае, если исключение не выполняется, else
выполняется, а except
- нет.
Это работает как ожидалось:
def divide(x, y):
print 'entering divide'
result = 0
try:
result = x/y
except:
print 'error'
else:
print 'no error'
finally:
print 'exit'
return result
print divide(1, 1)
print divide(1, 0)
Ответ 3
Блок else
не выполняется, потому что вы оставили функцию до того, как она получила возможность сделать это.
Однако блок finally
всегда выполняется (если вы не держите шнур питания или что-то в этом роде).
Рассмотрим это (как мысленный эксперимент, пожалуйста, не делайте этого в реальном коде):
def whoops():
try:
return True
finally:
return False
Посмотрите, что он возвращает:
>>> whoops()
False
Если вы считаете это запутанным, вы не одиноки. Некоторые языки, такие как С#, активно препятствуют вам размещать оператор return
в предложении finally
.
Ответ 4
"return" завершает функцию и возвращает все, что вы хотите вернуть. Так что это не будет продолжаться, конечно. "наконец" всегда выполняется.
Ответ 5
Почему не выполняется предложение else
?
Предложение A else
полезно для кода, который должен быть выполнен , если предложение try не вызывает исключение.
-
Когда вы вызываете divide(1, 0)
, предложение try
создает исключение ZeroDivisionError
, поэтому предложение else
не запускается.
-
Когда вы вызываете divide(1, 1)
, предложение try
выполняется успешно, и возвращает. Таким образом, предложение else
никогда не достигается.
Почему всегда выполняется предложение finally
?
A finally
условие всегда выполняется перед тем, как оставить оператор try, произошло ли исключение.
См. выше.
Ссылка https://docs.python.org/3.5/tutorial/errors.html