← Назад к вопросам
За что отвечает finally в блоке try...except
1.6 Junior🔥 211 комментариев
#Python Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Finally в блоке try...except
Finally — это часть обработки исключений, которая гарантирует выполнение кода независимо от того, произошла ошибка или нет.
Основная структура
try:
# Код, который может вызвать исключение
risky_code()
except SomeException:
# Код, который выполнится если было исключение SomeException
handle_error()
finally:
# Код, который ВСЕГДА выполнится
cleanup()
Все варианты выполнения
print("Начало")
try:
print("В try блоке")
# 1. Если ошибки нет
x = 10 / 2
except ZeroDivisionError:
print("Ошибка деления на 0")
finally:
print("Finally выполнится в любом случае")
print("Конец")
# Результат:
# Начало
# В try блоке
# Finally выполнится в любом случае
# Конец
Когда бывает исключение
print("Начало")
try:
print("В try блоке")
x = 10 / 0 # ZeroDivisionError!
except ZeroDivisionError:
print("Ошибка деления на 0")
finally:
print("Finally выполнится в любом случае")
print("Конец")
# Результат:
# Начало
# В try блоке
# Ошибка деления на 0
# Finally выполнится в любом случае
# Конец
Практический пример: закрытие файла
# БЕЗ finally (неправильно)
def read_file_bad():
f = open("data.txt", "r")
try:
data = f.read()
# Если здесь ошибка, файл не закроется!
process(data)
except Exception:
pass
# Файл остаётся открытым
# С finally (правильно)
def read_file_good():
f = open("data.txt", "r")
try:
data = f.read()
process(data)
except Exception:
print("Ошибка при обработке")
finally:
f.close() # Закроется в любом случае
# ИЛИ используй контекстный менеджер (лучше всего)
def read_file_best():
with open("data.txt", "r") as f:
data = f.read()
process(data)
# Файл автоматически закроется
Работа с ресурсами
import sqlite3
# Неправильно
def bad_db_access():
conn = sqlite3.connect(":memory:")
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
# Если ошибка — соединение не закроется
# Правильно с finally
def good_db_access():
conn = sqlite3.connect(":memory:")
try:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
return cursor.fetchall()
except Exception as e:
print(f"Ошибка БД: {e}")
finally:
conn.close() # Всегда закроется
# Лучше всего
def best_db_access():
with sqlite3.connect(":memory:") as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
return cursor.fetchall()
# Соединение закроется автоматически
Выполнение с return
Finally выполняется даже если в try или except есть return:
def example_with_return():
try:
print("1. try блок")
return "результат из try"
except Exception:
print("2. except блок")
finally:
print("3. finally выполнится перед return")
result = example_with_return()
print(f"4. результат: {result}")
# Результат:
# 1. try блок
# 3. finally выполнится перед return
# 4. результат: результат из try
Finally с исключением в except
def complex_example():
try:
print("1. try")
x = 1 / 0
except ZeroDivisionError:
print("2. except")
# Даже если нужно выбросить новое исключение
raise ValueError("Новая ошибка")
finally:
print("3. finally выполнится перед тем как выбросится ValueError")
try:
complex_example()
except ValueError as e:
print(f"4. Поймано: {e}")
# Результат:
# 1. try
# 2. except
# 3. finally выполнится перед тем как выбросится ValueError
# 4. Поймано: Новая ошибка
Else блок
Можно использовать else, который выполняется только если нет исключения:
try:
x = 10 / 2
except ZeroDivisionError:
print("Ошибка")
else:
print(f"Успех! Результат: {x}") # Выполнится только если нет ошибки
finally:
print("Finally всегда")
# Результат:
# Успех! Результат: 5.0
# Finally всегда
Практические применения finally
- Закрытие файлов и соединений
- Освобождение ресурсов (блокировки, потоки)
- Логирование и отчёты
- Откат транзакций в БД
import threading
def acquire_resource():
lock = threading.Lock()
try:
lock.acquire()
# Работа с защищённым ресурсом
do_something()
except Exception as e:
handle_error(e)
finally:
lock.release() # Освободить лок в любом случае
Контекстные менеджеры (лучшая практика)
Вместо finally лучше использовать with (контекстные менеджеры):
# Старый способ
f = open("file.txt")
try:
data = f.read()
finally:
f.close()
# Современный способ
with open("file.txt") as f:
data = f.read()
# Файл закроется автоматически
Итог
- finally выполняется всегда (даже при return, break, continue)
- Используй для очистки ресурсов (файлы, соединения, блокировки)
- Лучше использовать контекстные менеджеры (with) вместо try...finally
- finally не ловит исключения, а только гарантирует выполнение кода