Класс contextlib.ContextDecorator
позволяет использовать менеджер контекста как в качестве декоратора функции, так и в обычном операторе with
.
Например, иногда полезно обернуть функции или группы операторов с помощью регистратора, который может отслеживать время входа и время выхода. Вместо написания декоратора функции и диспетчера контекста для этой задачи, наследование класса contextlib.ContextDecorator()
предоставляет обе возможности в одном определении:
from contextlib import ContextDecorator import logging logging.basicConfig(level=logging.INFO) class track_entry_and_exit(ContextDecorator): def __init__(self, name): self.name = name def __enter__(self): logging.info('Entering: %s', self.name) def __exit__(self, exc_type, exc, exc_tb): logging.info('Exiting: %s', self.name)
Экземпляры этого класса могут использоваться как менеджер контекста:
with track_entry_and_exit('widget loader'): print('Some time consuming activity goes here') load_widget()
А также в качестве декоратора функции:
@track_entry_and_exit('widget loader') def activity(): print('Some time consuming activity goes here') load_widget()
Обратите внимание, что есть одно дополнительное ограничение при использовании менеджеров контекста в качестве декораторов функций: нет способа получить доступ к возвращаемому значению __enter__()
. Если это значение необходимо, то все равно необходимо использовать явный оператор with
.