Context manager
An object which controls the environment seen in a with statement by defining __enter__()
and __exit__()
methods.
See PEP 343.
Examples
-
Order of execution of magic methods in a class:
my_context_manager.pyclass MyClass(object): def __init__(self): print('__init__') self.name = 'Guido van Rossum' def __enter__(self): print('__enter__') return self def __exit__(self, type, value, traceback): print('__exit__') def __del__(self): print('__del__') with MyClass() as mc: print('body') print(mc.name)
-
A useful example could be a database connection object, which then automagically closes the connection once the corresponding
with
-statement goes out of scope: -
A template for opening a file that ensures the file is closed when the block is left:
from contextlib import contextmanager @contextmanager def opened_w_error(filename, mode="r"): try: f = open(filename, mode) except IOError, err: yield None, err else: try: yield f, None finally: f.close() with opened_w_error("/etc/passwd", "a") as (f, err): if err: print "IOError:", err else: f.write("guido::0:0::/:/bin/sh\n")
-
A template for committing or rolling back a database transaction:
-
A generic "object-closing" context manager:
class closing(object): def __init__(self, obj): self.obj = obj def __enter__(self): return self.obj def __exit__(self, *exc_info): try: close_it = self.obj.close except AttributeError: pass else: close_it() # emulate opening(): with closing(open("argument.txt")) as contradiction: for line in contradiction: print (line)
PEP 343 -- The «with» Statement
A new statement is proposed with the syntax:
, where:EXPR
is an arbitrary expression (but not an expression-list);VAR
is a single assignment target.
The translation of the above statement is:
mgr = (EXPR)
exit = type(mgr).__exit__ # Not calling it yet
value = type(mgr).__enter__(mgr)
exc = True
try:
try:
VAR = value # Only if "as VAR" is present
BLOCK
except:
# The exceptional case is handled here
exc = False
if not exit(mgr, *sys.exc_info()):
raise
# The exception is swallowed if exit() returns true
finally:
# The normal and non-local-goto cases are handled here
if exc:
exit(mgr, None, None, None)
Context Manager Types
With Statement Context Managers
A context manager is an object that defines the runtime context to be established when executing a with statement.
The context manager handles the entry into, and the exit from, the desired runtime context for the execution of the
block of code. Context managers are normally invoked using the with
statement, but can also be used by directly invoking their methods.
Typical uses of context managers include:
- saving and restoring various kinds of global state;
- locking and unlocking resources;
- closing opened files, etc.
Enter the runtime context related to this object: object.__enter__(self)
. The with
statement will bind this method’s return value to the target(s) specified in the as clause of the statement, if any.
Exit the runtime context related to this object: object.__exit__(self, exc_type, exc_value, traceback)
.
The parameters describe the exception that caused the context to be exited. If the context was exited without an
exception, all three arguments will be None
.
Note
Note that __exit__()
methods should not reraise the passed-in exception; this is the caller’s responsibility.
The with
statement
The with
statement is used to wrap the execution of a block with methods defined by a context manager. This allows common try…except…finally
usage patterns to be encapsulated for convenient reuse.