Slide 1

Slide 1 text

CONTEXT MANAGERS MEMPHIS PYTHON

Slide 2

Slide 2 text

with CONTEXT MANAGERS

Slide 3

Slide 3 text

with CONTEXT MANAGERS When you need to do something before and after your code runs.

Slide 4

Slide 4 text

try: … except: … finally: … CONTEXT MANAGERS Roughly replaces the try… except…finally pattern.

Slide 5

Slide 5 text

# Opening a file # (handles opening and closing cleanly) with open('example.txt') as f: print(f.read()) SOME EXAMPLES…

Slide 6

Slide 6 text

# 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…

Slide 7

Slide 7 text

# When mocking (in tests): with patch('my.module.Class') as mock_class: instance = mock_class() SOME EXAMPLES…

Slide 8

Slide 8 text

# In fabric tasks (see: fabfile.org) def list_dir(): with cd("/home/brad"): run("ls -l") SOME EXAMPLES…

Slide 9

Slide 9 text

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!

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

contextlib. ContextDecorator CONTEXT MANAGERS

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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