Короткий ответ
Контекстный менеджер — объект, который гарантирует корректное освобождение ресурсов вроде файлов и соединений с помощью оператора with. Метод __enter__() выполняется при входе в блок, а __exit__() — при выходе, который происходит всегда, даже если возникло исключение.
Как это работает подробнее
Конструкция with избавляет от ручной очистки ресурсов и заменяет громоздкие связки try/finally.
- События входа и выхода. Код внутри
withвыполняется между__enter__()и__exit__(), а выход гарантирован и при нормальном завершении, и при ошибке. - Сигнатура __exit__(). Метод принимает тип исключения, значение и traceback; если ошибки не было, все три аргумента равны
None. - Классический пример.
open()возвращает контекстный менеджер: файл автоматически закрывается на выходе из блока, вызыватьclose()явно не нужно. - Цена утечки. Без закрытия ресурсов система может исчерпать файловые дескрипторы и соединения, замедлиться или упасть.
Пример кода
Собственный контекстный менеджер для файла
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_value, traceback):
self.file.close()
with FileManager('test.txt', 'w') as f:
f.write('Test')
print(f.closed) # True — файл закрыт автоматическиЧто использовать на практике
- Файлы и соединения. Работай с ними через
with, чтобы не оставлять дескрипторы открытыми.