С помощью чего можно сделать свой контекстный менеджер

В питоне есть оператор with. Размещенный внутри код выполняется с особенностью: до и после гарантированно срабатывают события входа в блок withи выхода из него. Объект, который определяет эту логику, называется контекстным менеджером.

События входа и выхода из блока определены методами __enter__ и __exit__. Первый срабатывает в тот момент, когда ход исполнения программы переходит внутрь with. Метод может вернуть значение. Оно будет доступно низлежащему внутри блока with коду.

__exit__ срабатывает в момент выхода из блока, в т.ч. и по причине исключения. В этом случае в метод будет передана тройка значений (exc_class, exc_instance, traceback).

Самый распространённый контекстный менеджер – класс, порожденный функцией open. Он гарантирует, что файл будет закрыт даже в том случае, если внутри блока возникнет ошибка.

Нужно стараться выходить из контекстного менеджера как можно быстрее, чтобы освобождать контекст и ресурсы.

with open('file.txt') as f:
    data = f.read()
process_data(data)

Пример реализации своего контекстного менеджера на основе класса:

class Printable:
    def __enter__(self):
        print('enter')

    def __exit__(self, type, value, traceback):
        print('exit')

Пример реализации своего контекстного менеджера с использованием встроенной библиотеки contextlib:

from contextlib import contextmanager

@contextmanager
def printable():
    print('enter')
    try:
      yield
    finally:
      print('exit')

Контекстные менеджеры также можно использовать для временной замены параметров, переменных окружения, транзакций БД.

Oct. 10, 2023, Источник