Базовые конструкции
Что такое контекстный менеджер?
Короткий ответ
Контекстный менеджер - это объект, который определяет контекст выполнения блока кода с помощью методов __enter__()
и __exit__()
, чаще всего используется с оператором with
для автоматического управления ресурсами.
Развернутый ответ
Контекстный менеджер в Python — это объект, который определяет контекст выполнения блока кода с помощью оператора with
. Он гарантирует, что определенные действия будут выполнены при входе в контекст и при выходе из него (даже при возникновении исключения).
1. Основные возможности:
- Автоматическое выделение и освобождение ресурсов
- Обработка исключений внутри контекста
- Создание временных изменений состояния
- Измерение времени выполнения
2. Синтаксис с with
with контекстный_менеджер as переменная:
# Блок кода
# Автоматическое выполнение cleanup-действий
3. Реализация через класс
Класс должен содержать методы __enter__
и __exit__
:
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
if exc_type: # Если было исключение
print(f"Ошибка: {exc_val}")
return True # Подавляем исключение
# Использование
with FileManager('test.txt', 'w') as f:
f.write('Hello')
4. Реализация через contextlib.contextmanager
from contextlib import contextmanager
@contextmanager
def timer():
start = time.time()
try:
yield # Здесь выполняется код внутри with
finally:
print(f"Время: {time.time() - start:.2f} сек")
with timer():
time.sleep(1) # Выведет время выполнения
5. Встроенные контекстные менеджеры
open()
— работа с файламиthreading.Lock()
— блокировки потоковsubprocess.Popen()
— управление процессамиunittest.mock.patch()
— временные моки
6. Примеры использования
Работа с файлами
with open('file.txt', 'r') as f:
content = f.read() # Файл закроется автоматически
Блокировки потоков
lock = threading.Lock()
with lock:
# Критическая секция
shared_data.append(value)
Временное перенаправление вывода
with redirect_stdout(sys.stderr):
print("Это будет перенаправлено в stderr")
7. Параметры __exit__
exc_type
— тип исключенияexc_val
— экземпляр исключенияexc_tb
— объект трассировки
Если __exit__
возвращает True
, исключение подавляется.
8. Преимущества
- Упрощение управления ресурсами
- Гарантированное выполнение cleanup-кода
- Улучшение читаемости
- Безопасная обработка исключений
Контекстные менеджеры широко используются для работы с ресурсами (файлы, сетевые соединения, блокировки), временными изменениями состояния и измерениями производительности.