Блок finally: действия, которые выполняются всегда

Блок finally: действия, которые выполняются всегда Обработка исключений

Привет! Мы уже научились обрабатывать ошибки с помощью try-except и выполнять код при успехе через else. Но что, если нужно выполнить код в любом случае — была ошибка или нет?

Именно для этого существует блок finally.

В этой статье мы разберём:

  • Что такое finally
  • Когда он выполняется
  • Зачем нужен finally
  • Примеры использования

Что нужно знать перед началом

Для этого урока тебе понадобится:

  • Установленный Python
  • Базовое понимание try-except (статьи 1–4 в этом подменю)

Совет: finally — это гарантия, что важные действия (закрытие файлов, освобождение ресурсов) будут выполнены.

Основная часть

Что такое finally

finally — это блок, который выполняется всегда, независимо от того, возникла ошибка или нет.

try:
    print("Начало")
    result = 10 / 2
    print("Успешно")
except ZeroDivisionError:
    print("Ошибка")
finally:
    print("Это выполнится всегда")

Результат:

Начало
Успешно
Это выполнится всегда

finally при ошибке

try:
    print("Начало")
    result = 10 / 0
    print("Успешно")
except ZeroDivisionError:
    print("Ошибка")
finally:
    print("Это выполнится всегда")

Результат:

Начало
Ошибка
Это выполнится всегда

finally без except

finally можно использовать и без except.

try:
    file = open("data.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("Файл не найден")
finally:
    # Закрываем файл, даже если он не открылся
    print("Завершение работы")

finally vs else

БлокКогда выполняется
elseТолько если ошибки НЕ было
finallyВсегда
try:
    result = 10 / 2
except ZeroDivisionError:
    print("Ошибка")
else:
    print("Успешно")
finally:
    print("Это всегда")

Зачем нужен finally

finally используется для:

  • Закрытия файлов
  • Освобождения сетевых соединений
  • Закрытия подключений к БД
  • Логирования
  • Очистки ресурсов
def read_file_safe(filename):
    file = None
    try:
        file = open(filename, "r")
        return file.read()
    except FileNotFoundError:
        return "Файл не найден"
    finally:
        if file:
            file.close()
            print("Файл закрыт")

Пример с файлом

def process_file(filename):
    try:
        with open(filename, "r") as file:
            data = file.read()
            return data
    except FileNotFoundError:
        print("Файл не найден")
        return None
    finally:
        print("Обработка файла завершена")

Пример с БД

def get_user_from_db(user_id):
    connection = None
    try:
        connection = connect_to_db()
        cursor = connection.cursor()
        cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
        return cursor.fetchone()
    except ConnectionError:
        print("Ошибка подключения")
        return None
    finally:
        if connection:
            connection.close()
            print("Соединение закрыто")

finally с возвратом значения

Если в try или except есть returnfinally всё равно выполнится.

def safe_divide(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        return None
    finally:
        print("Деление выполнено")

Важно: finally выполняется до возврата значения.

 finally без try

finally не может существовать без try.

# Ошибка!
finally:
    print("Что-то")

Примеры из реальной жизни

Пример 1. Закрытие файла:

def read_config(filename):
    try:
        with open(filename, "r") as file:
            return file.read()
    except FileNotFoundError:
        print("Файл не найден")
        return None
    finally:
        print("Файл обработан")

Пример 2. Логирование:

def process_data(data):
    try:
        result = complex_operation(data)
        return result
    except ValueError:
        print("Ошибка в данных")
        return None
    finally:
        print(f"Обработка данных завершена: {data}")

Задачи для закрепления

Задача 1. Напиши программу, которая открывает файл и в любом случае выводит «Операция завершена».

Задача 2. Напиши функцию, которая делит два числа и в любом случае выводит «Деление выполнено».

Задача 3. В чём разница между else и finally?

Задача 4. Напиши функцию, которая подключается к БД и в любом случае закрывает соединение.

Задача 5. Будет ли выполнен finally, если в try произойдёт ошибка?

Ответы:

Задача 1.

try:
    with open("file.txt", "r") as file:
        content = file.read()
except FileNotFoundError:
    print("Файл не найден")
finally:
    print("Операция завершена")

Задача 2.

def safe_divide(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        return None
    finally:
        print("Деление выполнено")

Задача 3.

# else — выполняется при успехе
# finally — выполняется всегда

Задача 4.

def get_user(user_id):
    connection = None
    try:
        connection = connect_to_db()
        return connection.query(f"SELECT * FROM users WHERE id={user_id}")
    except ConnectionError:
        return None
    finally:
        if connection:
            connection.close()

Задача 5.

# Да, finally выполняется всегда, даже при ошибке

Нюансы и подводные камни

finally может переопределить return

def test():
    try:
        return 1
    finally:
        return 2

print(test())   # 2 (finally переопределил return)

Важно: Если finally содержит return, он переопределяет значение из try или except.

finally не должен содержать ошибок

Если в finally возникает ошибка, она не будет обработана (если только не обёрнута в другой try).

try:
    result = 10 / 2
except ZeroDivisionError:
    print("Ошибка")
finally:
    result = 1 / 0   # Ошибка! Не перехватывается

finally без except

try:
    result = 10 / 2
finally:
    print("Завершено")
# Если ошибка — она не будет перехвачена, но finally выполнится

Частые ошибки и как их избежать

Ошибка 1: finally без try

finally:   # Ошибка!
    print("Что-то")

Ошибка 2: Ошибка в finally

try:
    result = 10 / 2
finally:
    print(1 / 0)   # Ошибка не обрабатывается

Ошибка 3: finally не должен содержать return

def test():
    try:
        return 1
    finally:
        return 2   # Переопределяет return из try

Шпаргалка

Что нужноКак пишется
Блок всегдаfinally:
finally без excepttry: ... finally: ...
finally после excepttry: ... except: ... finally: ...
finally с elsetry: ... except: ... else: ... finally: ...

Заключение / Выводы

Сегодня мы узнали:

  • finally — выполняется всегда
  • Используется для освобождения ресурсов
  • Отличие finally от else
  • finally может переопределить return

КВИЗ

Что дальше?

Оцените статью
IMI-DS - PYTHON LERNEN
Содержание
Оглавление ×