← Назад к вопросам
Приведи пример использования контекстного менеджера
2.3 Middle🔥 161 комментариев
#Python Core#Архитектура и паттерны
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Контекстные менеджеры в Python
Контекстный менеджер — это объект, который определяет, что происходит при входе в блок with и при выходе из него. Это очень полезный инструмент для управления ресурсами (файлы, подключения, блокировки и т.д.).
Базовый пример: работа с файлами
# Без контекстного менеджера (плохо)
f = open("data.txt", "r")
data = f.read()
f.close() # может не выполниться, если будет ошибка
# С контекстным менеджером (хорошо)
with open("data.txt", "r") as f:
data = f.read()
# файл автоматически закроется, даже если будет исключение
В этом примере объект f — контекстный менеджер, который гарантирует закрытие файла в любом случае.
Создание собственного контекстного менеджера
Твой класс должен реализовать методы __enter__ и __exit__:
class DatabaseConnection:
def __init__(self, db_url):
self.db_url = db_url
self.connection = None
def __enter__(self):
print(f"Подключаюсь к базе: {self.db_url}")
self.connection = self._create_connection()
return self.connection # это значение присваивается переменной после as
def __exit__(self, exc_type, exc_val, exc_tb):
print("Закрываю соединение")
if self.connection:
self.connection.close()
# возвращаем False, чтобы исключения распространялись дальше
return False
def _create_connection(self):
# здесь логика подключения
return "connection_object"
# Использование
with DatabaseConnection("postgresql://localhost") as conn:
print(f"Работаю с: {conn}")
# даже если здесь будет ошибка, __exit__ выполнится
Использование декоратора contextmanager
Есть более простой способ с модулем contextlib:
from contextlib import contextmanager
@contextmanager
def database_connection(db_url):
print(f"Подключаюсь к: {db_url}")
conn = f"connection_{db_url}" # имитация подключения
try:
yield conn # отдаём ресурс в блок with
finally:
print(f"Закрываю: {conn}") # гарантированно выполнится
# Использование
with database_connection("postgres://localhost") as conn:
print(f"Использую: {conn}")
Практический пример: работа с файлами и логированием
from contextlib import contextmanager
import logging
@contextmanager
def logged_operation(operation_name):
logger = logging.getLogger(__name__)
logger.info(f"Начинаю: {operation_name}")
try:
yield
except Exception as e:
logger.error(f"Ошибка в {operation_name}: {e}")
raise
finally:
logger.info(f"Завершил: {operation_name}")
# Использование
with logged_operation("Импорт данных"):
# твой код здесь
data = [1, 2, 3]
print(f"Обработано: {len(data)} элементов")
Пример с несколькими ресурсами
# Python 3.10+ позволяет использовать несколько менеджеров
with open("input.txt") as input_file, open("output.txt", "w") as output_file:
for line in input_file:
output_file.write(line.upper())
# оба файла закроются автоматически
Почему контекстные менеджеры важны
- Безопасность ресурсов — гарантируют очистку даже при исключениях
- Читаемость — код понятнее и структурнее
- Избежание утечек — файлы, подключения, блокировки всегда закрываются
- Меньше кода — не нужно помнить о
finallyблоках
Контекстные менеджеры — это один из принципов правильного управления ресурсами в Python.