Страницы

Поиск по вопросам

пятница, 27 декабря 2019 г.

contextmanager vs __enter__()/__exit__()

#python


Есть два варианта для реализации менеджера контекста:


С помощью декоратора @contextmanager
С помощью написания методов __enter__() и __exit__()


Мне бы хотелось узнать мнение опытных, когда лучше использовать п.1, а когда п.2 ?

Я пока исхожу из соображений, что если код небольшой и можно поместить в одну функцию,
тогда п.2.
    


Ответы

Ответ 1



@contextmanager обычно удобнее, реализацию с классами возможно стоит использовать, если хочется проинспектировать бэктрейс, не заглядывая в traceback. Чуть более конкретно: Если менеджер используется для RAII, важно окружать yield блоком try-finally Если нужно подавлять исключение определенного типа, это можно сделать с помощью except Состояние, которое в реализации напрямую через классы бы сохранялось в полях класса, естественнее хранить в локальных переменных функции-генератора. Подробнее: Fluent Python Перевод PEP-343 Включает реализацию @contextmanager

Ответ 2



Ответ моего коллеги известного как ysegorov: __enter__/__exit__ - когда есть необходимость хранить какое-то состояние в инстансе и сам объект может использоваться не только в менеджере контекста самый хороший пример - транзакция в базе. На __enter__ создается курсор, внутри контекста делаются операции и на выходе делается commit или rollback в зависимости от состояния операции В качестве примера можно посмотреть реализацию класса PgTransaction на GitHub.

Комментариев нет:

Отправить комментарий