Что вернет функция foo()?
def foo(): try: return 'try' finally: return 'finally' foo()
Правильный ответ будет ‘finally’:
Дело в том, что функция возвращает результат последнего выполненного return. А, учитывая, что блок finally всегда выполняется, то будет выполнено два return, последний из них будет return ‘finally’.
Что будет при вложенных блоках finally?
# вспомогательная функция, чтобы считать return-ы def returner(s): print(f' return {s}') return s def foo(): try: return returner('try') finally: return returner('finally') print('Result: ', foo()) print('-' * 50) def baz(): try: try: return returner('try') finally: return returner('finally inner') finally: return returner('finally outer') print('Result: ', baz())
Вывод:
return try return finally Result: finally -------------------------------------------------- return try return finally inner return finally outer Result: finally outer
Как видим срабатывают все return (срабатывают, значит вычисляются аргументы выражения return), но будет возвращен из функции результат только последнего return.
Еще один коварный вопрос про try и finally.
Что будет при выполнении кода?
for i in range(10): try: print(1 / i) finally: print('finally') break
На первой итерации цикла произойдет исключение из-за деления на 0. Блока except нет. Но тем не менее исключение все равно будет подавлено, потому что в блоке finally есть break. Вот такая особенность языка. В будущих версиях (3.8+) тоже самое должно работать и с конструкцией continue.
🧙 Специально для канала @pyway. Подписывайтесь на мой канал в Телеграм @pyway 👈