Context Managers

Context Managers

A quick look at python context managers -- a short talk given at the Memphis Python User Group (March 2016). http://mempy.org

D57aec10399cbb252bd890c2bb3fe1c9?s=128

Brad Montgomery

March 22, 2016
Tweet

Transcript

  1. CONTEXT MANAGERS MEMPHIS PYTHON

  2. with CONTEXT MANAGERS

  3. with CONTEXT MANAGERS When you need to do something before

    and after your code runs.
  4. try: … except: … finally: … CONTEXT MANAGERS Roughly replaces

    the try… except…finally pattern.
  5. # Opening a file # (handles opening and closing cleanly)

    with open('example.txt') as f: print(f.read()) SOME EXAMPLES…
  6. # Ensuring DB queries are atomic # (e.g. with Django's

    ORM) from django.db import transaction with transaction.atomic(): user = User.objects.create(...) user.profile.update(...) user.profile.save() SOME EXAMPLES…
  7. # When mocking (in tests): with patch('my.module.Class') as mock_class: instance

    = mock_class() SOME EXAMPLES…
  8. # In fabric tasks (see: fabfile.org) def list_dir(): with cd("/home/brad"):

    run("ls -l") SOME EXAMPLES…
  9. class Timed(): def __enter__(self): self.start = time() def __exit__(self, type,

    value, traceback): self.end = time() with Timed(): print("sleeping for 2...") sleep(2) BUILD YOUR OWN!
  10. from contextlib import contextmanager @contextmanager def timed(): start = time()

    yield end = time() with timed(): print("sleeping for 2...") sleep(2) BUILD YOUR OWN!
  11. from contextlib import contextmanager @contextmanager def timed(): start = time()

    yield end = time() with timed(): print("sleeping for 2...") sleep(2) assert(False) # fails... WHOOPS, EXCEPTIONS
  12. from contextlib import contextmanager @contextmanager def robust_timed(): start = time()

    try: yield finally: end = time() with robust_timed(): print("sleeping for 2...") sleep(2) assert(False) # the timer finishes WHOOPS, EXCEPTIONS
  13. def __exit__(self, type, value, traceback): # This code is guaranteed

    to run print("type: {}".format(type)) print("value: {}".format(value)) print("traceback: {}".format(traceback)) self.end = time() total = self.end - self.start print(“End: {} (total: {})”.format( self.end, total)) with Timed(): print("sleeping for 2...") sleep(2) assert(False) # Timed will finish WHOOPS, EXCEPTIONS
  14. with Timed() as timer: print("sleeping for 2...") sleep(2) t =

    time() + timer.start() print("started {}s ago".format(t) sleep(2) SUPPORT FOR as
  15. with Timed() as timer: print("sleeping for 2...") sleep(2) t =

    time() - timer.start print("started {}s ago".format(t)) sleep(2) # within the Timed class def __enter__(self): self.start = time() return self SUPPORT FOR as
  16. contextlib. ContextDecorator CONTEXT MANAGERS

  17. from contextlib import ContextDecorator # Using the ContextDecorator allows us

    to use # this as a decorator, too! class bettertimed(ContextDecorator): def __enter__(self): self.start = time() return self def __exit__(self, type, value, traceback): self.end = time() total = self.end - self.start THE CONTEXT DECORATOR CLASS
  18. with bettertimed(): sleep(1) print("ok... ") sleep(1) @bettertimed() def slow_print(text): sleep(1)

    print(text) sleep(1) slow_print('oh bother') THE CONTEXT DECORATOR CLASS
  19. RESOURCES • http://preshing.com/20110920/the-python-with- statement-by-example/ • https://docs.python.org/3/library/ contextlib.html • Code: https://gist.github.com/bradmontgomery/

    4f4934893388f971c6c5