(continued from previous page) self.handler.close() # implicit return of None => don't swallow exceptions To illustrate how it works, we can add the following block of code to the above: If you specify a level value, the logger’s level is set to that value in the scope of the with block covered by the context manager. If you specify a handler, it is added to the logger on entry to the block and removed on exit from the block. You can also ask the manager to close the handler for you on block exit - you could do this if you don’t need the handler any more. We initially set the logger’s level to$_{INFO}$ , so message #1 appears and message #2 doesn’t. We then change the level to$_{DEBUG}$ temporarily in the following$_{with}$ block, and so message #3 appears. After the block exits, the logger’s level is restored to$_{INFO}$ and so message #4 doesn’t appear. In the next$_{with}$ block, we set the level to$_{DEBUG}$ again but also add a handler writing to$_{sys.stdout}$ . Thus, message #5 appears twice on the console (once via$_{stderr}$ and once via$_{stdout}$). After the$_{with}$ statement’s completion, the status is as it was before so message #6 appears (like message #1) whereas message #7 doesn’t (just like message #2). If we run the resulting script, the result is as follows: If we run it again, but pipe$_{stderr}$ to$_{/dev/null}$ , we see the following, which is the only message written to stdout : Once again, but piping$_{stdout}$to$_{/dev/null}$ , we get: $ python logctx.py 2>/dev/null 5. This should appear twice - once on stderr and once on stdout. In this case, the message #5 printed to$_{stdout}$doesn’t appear, as expected. Of course, the approach described here can be generalised, for example to attach logging filters temporarily. Note that the above code works in Python 2 as well as Python 3. 40 $ python logctx.py >/dev/null 1. This should appear just once on stderr. 3. This should appear once on stderr. 5. This should appear twice - once on stderr and once on stdout. 6. This should appear just once on stderr. $ python logctx.py 1. This should appear just once on stderr. 3. This should appear once on stderr. 5. This should appear twice - once on stderr and once on stdout. 5. This should appear twice - once on stderr and once on stdout. 6. This should appear just once on stderr. if __name__ =='__main__ ': logger=logging.getLogger('foo') logger.addHandler(logging .StreamHandler()) logger.setLevel(logging .INFO) logger.info('1. This should appear just once on stderr. ') logger.debug( '2. This should not appear. ') with LoggingContext(logger, level =logging.DEBUG): logger.debug( '3. This should appear once on stderr. ') logger.debug( '4. This should not appear. ') h =logging.StreamHandler(sys .stdout) with LoggingContext(logger, level =logging.DEBUG, handler=h, close= True ): logger.debug( '5. This should appear twice - once on stderr and once on ␣ ↪ → stdout. ') logger.info('6. This should appear just once on stderr. ') logger.debug( '7. This should not appear. ')