Lecture 29-30-Context Manager
Lecture 29-30-Context Manager
Oxford dictionary: The circumstances that form the setting for an event, statement, or
idea, and in terms of which it can be fully understood.
# module.py
global scope
f = open('test.txt', 'r') f → a file object
print(f.readlines())
f.close()
→ global scope
Managing the context of a block of code
There could be an exception before we close the file → file remains open!
f = open('test.txt', 'r')
try:
perform_work(f)
finally:
f.close()
Very useful for anything that needs to provide Enter / Exit Start / Stop Set / Reset
Works even if inside a function and a return is in the try or except blocks
Very useful for writing code that should execute no matter what happens
Example
with open(file_name) as f: enter the context (optional) an object is returned
# file is now open
exit the context
# file is now closed
The context management protocol
over simplified
with CtxManager() as obj: # do mgr = CtxManager() obj =
something exception handling
# done with context mgr.__enter__() try:
# do something
finally:
# done with context
mgr.__exit__()
Use Cases
Very common usage is for opening a file (creating resource) and closing the file (releasing resource)
Context managers can be used for much more than creating and releasing resources
Common Patterns
• Open – Close
• Lock – Release
• Change – Reset
• Start – Stop
• Enter – Exit
Examples
• file context managers
• Decimal contexts
How Context Protocol Works class MyClass:
def __init__(self): # init class
works in conjunction with a with statement
after the with block, or if an exception occurs inside the with block:
→ my_instance.__exit__ is called
Scope of with block
The with block is not like a function or a comprehension
The scope of anything in the with block (including the object returned from __enter__) is in the same scope
with open(fname) as f:
row = next(f)
row
i
s
a
l
s
The __enter__ method
def __enter__(self):
More complicated…
Remember the finally in a try statement? → always runs even if an exception occurs
→ it also needs to tell Python whether to silence the exception, or let it propagate
The __exit__ Method
with MyContext() as obj:
raise ValueError
print ('done')
Scenario 1
__exit__ receives error, performs some clean up and silences error
no exception is seen
Scenario 2
__exit__ receives error, performs some clean up
and let's error propagate
Open File
operate on open file
Close File
Start timer
perform operations
Stop timer
Pattern: Lock - Release
thread lock
Pattern: Change - Reset