>>> import logging
>>> logging.basicConfig(level=logging.INFO)
>>> @contextmanager
-... def track_entry_and_exit():
-... logging.info('Entry')
+... def track_entry_and_exit(name):
+... logging.info('Entering: {}'.format(name))
... yield
-... logging.info('Exit')
+... logging.info('Exiting: {}'.format(name))
Formerly, this would have only been usable as a context manager:
->>> with track_entry_and_exit():
+>>> with track_entry_and_exit('widget loader'):
... print('Some time consuming activity goes here')
+... load_widget()
Now, it can be used as a decorator as well:
->>> @track_entry_and_exit
+>>> @track_entry_and_exit('widget loader')
... def activity():
-... print('Some time consuming activity goes here'
+... print('Some time consuming activity goes here')
+... load_widget()
Trying to fulfill two roles at once places some limitations on the technique.
Context managers normally have the flexibility to return an argument usable by
-the :keyword:`with`-statement, and function decorators can be constructed to
-accept arguments or to know the name of the function they are enclosing. Since
-those features of context managers and function decorators are not overlapping,
-those features are not supported.
-
-In the above example, there is not a clean way for the
-:func:`track_entry_and_exit` decorator to know the name of the enclosed
-function. Likewise, the *track_entry_and_exit* context manager does not have a
-way to return a logging instance for use in the body of enclosed statements.
+the :keyword:`with`-statement, but there is no parallel for function decorators.
+
+In the above example, there is not a clean way for the *track_entry_and_exit*
+context manager does not have a way to return a logging instance for use in the
+body of enclosed statements.
(Contributed by Michael Foord in :issue:`9110`.)