Главная идея: в конструкции try/except/finally блок finally выполняется всегда — и перед выходом из функции, и при исключениях, и даже если в try уже выполнен return. При этом return внутри finally имеет приоритет и заменяет любое ранее вычисленное значение возврата.
Что происходит внутри 𝚏𝚘𝚘():
🔘Заходим в блок 𝚝𝚛𝚢, выполняется 𝚛𝚎𝚝𝚞𝚛𝚗 "𝚝𝚛𝚢" — Python запоминает, что функция должна вернуть "try", но перед реальным выходом обязан выполнить 𝚏𝚒𝚗𝚊𝚕𝚕𝚢.
🔘Заходим в блок 𝚏𝚒𝚗𝚊𝚕𝚕𝚢:
▸ 𝚙𝚛𝚒𝚗𝚝("𝚏𝚒𝚗𝚊𝚕𝚕𝚢") — на экран выводится первая строка finally.
▸ 𝚛𝚎𝚝𝚞𝚛𝚗 "𝚏𝚒𝚗𝚊𝚕𝚕𝚢" — это новое значение возврата, которое перезаписывает ранее подготовленный 𝚛𝚎𝚝𝚞𝚛𝚗 "𝚝𝚛𝚢".
В итоге 𝚏𝚘𝚘() возвращает "finally".
Что печатает 𝚙𝚛𝚒𝚗𝚝:
🔘Внутри 𝚏𝚘𝚘(): печатается finally.
🔘Снаружи: 𝚙𝚛𝚒𝚗𝚝(𝚏𝚘𝚘()) печатает возвращённое значение "finally".
Итоговый вывод в терминале: finally finally. То есть первая строка — побочный эффект из 𝚏𝚒𝚗𝚊𝚕𝚕𝚢, вторая — результат возврата функции.
Почему это важно
🔘𝚏𝚒𝚗𝚊𝚕𝚕𝚢 всегда выполняется: при нормальном завершении, при return, при исключении.
🔘𝚛𝚎𝚝𝚞𝚛𝚗 внутри 𝚏𝚒𝚗𝚊𝚕𝚕𝚢 перетирает результат 𝚝𝚛𝚢/𝚎𝚡𝚌𝚎𝚙𝚝, поэтому так писать опасно: легко скрыть реальные ошибки или неожиданные возвраты.
🔘Рекомендуется не использовать 𝚛𝚎𝚝𝚞𝚛𝚗 в 𝚏𝚒𝚗𝚊𝚕𝚕𝚢; лучше ограничиваться чистым cleanup — закрытием файлов, соединений и т.п.
Post #4481
809
- 👍 5