Chapter 27. Managing Contexts: the
with
Statement
Many objects manage resources, and must impose a rigid protocol on
use of that resource. A file object in Python acquires and releases OS
files, which may be associated with devices or network interfaces. A
program may acquire and release database connections. In some cases, there
may be a nested context of a database connection and one or more
cursors.
In Python 2.6, the
with
statement interacts with
certain types of context management objects to assure that the protocol
for acquiring and releasing the object is followed irrespective of any
exceptions that may be raised.
In Python 2.5, we must enable the
with
statement
by using the following statement.
from __future__ import with_statement
In this section, we'll look at ways in which the new
with
statement will simplify file processing or
database processing. We will look at the kinds of object design
considerations which are required to create your own objects that work
well with the
with
statement.
While most use of the
with
statement involve
acquiring and releasing specific resources, the statement can be applied
somewhat more generally. To make the statement more widely applicable,
Python works with a context. A context is not
limited to acquiring and releasing a file or database connection. A
context could be a web transaction, a user's logged-in session, a
particular transaction or any other stateful condition.
Generally, a context is a state which must endure for one or more
statements, has a specific method for entering the state and has a
specific method for exiting the state. Further, a context's exit must be
done with the defined method irrespective of any exceptions that might
occur within the context.
Database operations often center on transactions which must either
be completed (to move the database to a new, iternally consistent
state,) or rolled back to reset the database to a prior consistent
state. In this case, exceptions must be tolerated so that the database
server can be instructed to commit the transaction or roll it
back.
We'll also use a context to be sure that a file is closed, or a
lock is released. We can also use a context to be sure that the user
interface is reset properly when a user switches their focus or an error
occurs in a complex interaction.
The design pattern has two elements: a
Context Manager
and a
Working Object
. The Context Manager is used by
the
with
statement to enter and exit the context. One
thing that can happen when entering a context is that a Working Object
is created as part of the entry process. The Working Object is often
used for files and databases where we interact with the context. The
Working Object isn't always necessary; for example acquiring and
releasing locks is done entirely by the Context Manager.