Контекстные менеджеры

Что такое контекстный менеджер?

подробнее

Контекстный менеджер — объект, который управляет входом и выходом из контекста выполнения кода (обычно через with).
Метод __enter__() — выполняется при входе в блок with.
Метод __exit__(exc_type, exc_val, exc_tb) — выполняется при выходе (закрытие ресурсов, обработка ошибок).
Назначение: автоматическое управление ресурсами (файлы, соединения, блокировки).

Пример:

with open("file.txt", "r") as f:
    data = f.read()
# файл автоматически закрыт

Какие параметры принимает метод __exit__()?

подробнее

Метод __exit__ контекстного менеджера принимает 3 параметра:

  • exc_type – класс исключения (или None, если исключения нет).
  • exc_value – объект исключения (или None).
  • traceback – объект трассировки стека (или None).

Возвращает:

  • True — подавляет исключение.
  • False или None — пробрасывает исключение дальше.

Как реализовать свой контекстный менеджер?

подробнее

Через класс с __enter__() и __exit__():

class MyContext:
    def __enter__(self):
        print("Входим")
        return self  # объект, доступный в as
    def __exit__(self, exc_type, exc_value, traceback):
        print("Выходим")
        return False  # False — исключения не подавлять

with MyContext() as mc:
    print("Внутри")

Через декоратор contextlib.contextmanager:

from contextlib import contextmanager

@contextmanager
def my_context():
    print("Входим")
    try:
        yield "Данные" # точка передачи управления в блок with
    finally:
        print("Выходим")

with my_context() as value:
    print("Внутри", value)

Декоратор @contextmanager

подробнее

@contextmanager — декоратор из модуля contextlib, позволяющий писать контекстные менеджеры как генераторы вместо класса с __enter__ / __exit__.

Пример:

from contextlib import contextmanager

@contextmanager
def my_context():
    print("Входим")
    try:
        yield "Данные"
    finally:
        print("Выходим")

with my_context() as value:
    print("Внутри:", value)