Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
c25a3f21
Commit
c25a3f21
authored
Apr 23, 2006
by
Andrew M. Kuchling
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Edits to the PEP 343 section
parent
75a363c0
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
62 additions
and
65 deletions
+62
-65
Doc/whatsnew/whatsnew25.tex
Doc/whatsnew/whatsnew25.tex
+62
-65
No files found.
Doc/whatsnew/whatsnew25.tex
View file @
c25a3f21
...
@@ -585,8 +585,7 @@ executed.
...
@@ -585,8 +585,7 @@ executed.
In this section, I'll discuss the statement as it will commonly be
In this section, I'll discuss the statement as it will commonly be
used. In the next section, I'll examine the implementation details
used. In the next section, I'll examine the implementation details
and show how to write objects called ``context managers'' and
and show how to write objects for use with this statement.
``contexts'' for use with this statement.
The '
\keyword
{
with
}
' statement is a new control-flow structure whose
The '
\keyword
{
with
}
' statement is a new control-flow structure whose
basic structure is:
basic structure is:
...
@@ -596,13 +595,13 @@ with expression [as variable]:
...
@@ -596,13 +595,13 @@ with expression [as variable]:
with-block
with-block
\end{verbatim}
\end{verbatim}
The expression is evaluated, and it should result in a
type of objec
t
The expression is evaluated, and it should result in a
n object tha
t
that's called a context manager. The context manager can
return a
supports the context management protocol. This object may
return a
value that can optionally be bound to the name
\var
{
variable
}
. (Note
value that can optionally be bound to the name
\var
{
variable
}
. (Note
carefully
:
\var
{
variable
}
is
\emph
{
not
}
assigned the result of
carefully
that
\var
{
variable
}
is
\emph
{
not
}
assigned the result of
\var
{
expression
}
.)
One method of the context manager is run befor
e
\var
{
expression
}
.)
The object can then run set-up cod
e
\var
{
with-block
}
is executed, and another method is run after th
e
before
\var
{
with-block
}
is executed and some clean-up cod
e
block is done, even if the block raised an exception.
is executed after the
block is done, even if the block raised an exception.
To enable the statement in Python 2.5, you need
To enable the statement in Python 2.5, you need
to add the following directive to your module:
to add the following directive to your module:
...
@@ -613,7 +612,8 @@ from __future__ import with_statement
...
@@ -613,7 +612,8 @@ from __future__ import with_statement
The statement will always be enabled in Python 2.6.
The statement will always be enabled in Python 2.6.
Some standard Python objects can now behave as context managers. File
Some standard Python objects now support the context management
protocol and can be used with the '
\keyword
{
with
}
' statement. File
objects are one example:
objects are one example:
\begin{verbatim}
\begin{verbatim}
...
@@ -637,12 +637,11 @@ with lock:
...
@@ -637,12 +637,11 @@ with lock:
...
...
\end{verbatim}
\end{verbatim}
The lock is acquired before the block is executed
,
and always released once
The lock is acquired before the block is executed and always released once
the block is complete.
the block is complete.
The
\module
{
decimal
}
module's contexts, which encapsulate the desired
The
\module
{
decimal
}
module's contexts, which encapsulate the desired
precision and rounding characteristics for computations, can also be
precision and rounding characteristics for computations, also work.
used as context managers.
\begin{verbatim}
\begin{verbatim}
import decimal
import decimal
...
@@ -660,47 +659,45 @@ with decimal.Context(prec=16):
...
@@ -660,47 +659,45 @@ with decimal.Context(prec=16):
\subsection
{
Writing Context Managers
\label
{
context-managers
}}
\subsection
{
Writing Context Managers
\label
{
context-managers
}}
Under the hood, the '
\keyword
{
with
}
' statement is fairly complicated.
Under the hood, the '
\keyword
{
with
}
' statement is fairly complicated.
Most people will only use '
\keyword
{
with
}
' in company with
Most people will only use '
\keyword
{
with
}
' in company with existing
existing objects that are documented to work as context managers, and
objects and don't need to know these details, so you can skip the
don't need to know these details, so you can skip the following section if
following section if you like. Authors of new objects will need to
you like. Authors of new context managers will need to understand the
understand the details of the underlying implementation.
details of the underlying implementation.
A high-level explanation of the context management protocol is:
A high-level explanation of the context management protocol is:
\begin{itemize}
\begin{itemize}
\item
The expression is evaluated and should result in an object
\item
The expression is evaluated and should result in an object
that's a context manager, meaning that it has a
with a
\method
{__
context
__
()
}
method.
\method
{__
context
__
()
}
method.
\item
This object's
\method
{__
context
__
()
}
method is called, and must
\item
This object's
\method
{__
context
__
()
}
method is called, and must
return a context object.
return another object that has
\method
{__
enter
__
()
}
and
\method
{__
exit
__
()
}
.
\item
Th
e context's
\method
{__
enter
__
()
}
method is called.
\item
Th
is object's
\method
{__
enter
__
()
}
method is called. The value
The value returned is assigned to
\var
{
VAR
}
. If no
\code
{
'as
\var
{
VAR
}
'
}
returned is assigned to
\var
{
VAR
}
. If no
\code
{
'as
\var
{
VAR
}
'
}
clause
clause
is present, the value is simply discarded.
is present, the value is simply discarded.
\item
The code in
\var
{
BLOCK
}
is executed.
\item
The code in
\var
{
BLOCK
}
is executed.
\item
If
\var
{
BLOCK
}
raises an exception, the
context object's
\item
If
\var
{
BLOCK
}
raises an exception, the
\method
{__
exit
__
(
\var
{
type
}
,
\var
{
value
}
,
\var
{
traceback
}
)
}
is called
\method
{__
exit
__
(
\var
{
type
}
,
\var
{
value
}
,
\var
{
traceback
}
)
}
is called
with the exception's information, the same values returned by
with the exception's information, the same values returned by
\function
{
sys.exc
_
info()
}
. The method's return value
\function
{
sys.exc
_
info()
}
. The method's return value controls whether
controls whether the exception is re-raised: any false value
the exception is re-raised: any false value re-raises the exception,
re-raises the exception, and
\code
{
True
}
will result in suppressing it.
and
\code
{
True
}
will result in suppressing it. You'll only rarely
You'll only rarely want to suppress the exception; the
want to suppress the exception; the author of the code containing the
author of the code containing the '
\keyword
{
with
}
' statement will
'
\keyword
{
with
}
' statement will never realize anything went wrong.
never realize anything went wrong.
\item
If
\var
{
BLOCK
}
didn't raise an exception,
\item
If
\var
{
BLOCK
}
didn't raise an exception,
the
context object's
\method
{__
exit
__
()
}
is still called,
the
\method
{__
exit
__
()
}
method
is still called,
but
\var
{
type
}
,
\var
{
value
}
, and
\var
{
traceback
}
are all
\code
{
None
}
.
but
\var
{
type
}
,
\var
{
value
}
, and
\var
{
traceback
}
are all
\code
{
None
}
.
\end{itemize}
\end{itemize}
Let's think through an example. I won't present detailed code but
Let's think through an example. I won't present detailed code but
will only sketch the
necessary code. The example will be writing a
will only sketch the
methods necessary for a database that supports
context manager for a database that supports
transactions.
transactions.
(For people unfamiliar with database terminology: a set of changes to
(For people unfamiliar with database terminology: a set of changes to
the database are grouped into a transaction. Transactions can be
the database are grouped into a transaction. Transactions can be
...
@@ -721,15 +718,15 @@ with db_connection as cursor:
...
@@ -721,15 +718,15 @@ with db_connection as cursor:
# ... more operations ...
# ... more operations ...
\end{verbatim}
\end{verbatim}
The transaction should
either
be committed if the code in the block
The transaction should be committed if the code in the block
runs flawlessly
,
or rolled back if there's an exception.
runs flawlessly or rolled back if there's an exception.
First, the
\class
{
DatabaseConnection
}
needs a
\method
{__
context
__
()
}
First, the
\class
{
DatabaseConnection
}
needs a
\method
{__
context
__
()
}
method. Sometimes an object can
be its own context manager and can
method. Sometimes an object can
simply return
\code
{
self
}
; the
simply return
\code
{
self
}
; the
\module
{
threading
}
module's lock objects
\module
{
threading
}
module's lock objects do this, for example. For
can do this. For our database example, though, we need to
our database example, though, we need to create a new object; I'll
c
reate a new object; I'll call this class
\class
{
DatabaseContext
}
.
c
all this class
\class
{
DatabaseContext
}
. Our
\method
{__
context
__
()
}
Our
\method
{__
context
__
()
}
must therefore look like this:
method
must therefore look like this:
\begin{verbatim}
\begin{verbatim}
class DatabaseConnection:
class DatabaseConnection:
...
@@ -746,9 +743,9 @@ class DatabaseConnection:
...
@@ -746,9 +743,9 @@ class DatabaseConnection:
"Rolls back current transaction"
"Rolls back current transaction"
\end{verbatim}
\end{verbatim}
The context needs the connection object so that the connection
Instance of
\class
{
DatabaseContext
}
need the connection object so that
object's
\method
{
commit()
}
or
\method
{
rollback()
}
methods can be
the connection object's
\method
{
commit()
}
or
\method
{
rollback()
}
called:
methods can be
called:
\begin{verbatim}
\begin{verbatim}
class DatabaseContext:
class DatabaseContext:
...
@@ -756,12 +753,11 @@ class DatabaseContext:
...
@@ -756,12 +753,11 @@ class DatabaseContext:
self.connection = connection
self.connection = connection
\end{verbatim}
\end{verbatim}
The
\method
{__
enter
__
()
}
method is pretty easy, having only
The
\method
{__
enter
__
()
}
method is pretty easy, having only to start
to start a new transaction. In this example,
a new transaction. For this application the resulting cursor object
the resulting cursor object would be a useful result,
would be a useful result, so the method will return it. The user can
so the method will return it. The user can
then add
\code
{
as cursor
}
to their '
\keyword
{
with
}
' statement to bind
then add
\code
{
as cursor
}
to their '
\keyword
{
with
}
' statement
the cursor to a variable name.
to bind the cursor to a variable name.
\begin{verbatim}
\begin{verbatim}
class DatabaseContext:
class DatabaseContext:
...
@@ -798,17 +794,18 @@ class DatabaseContext:
...
@@ -798,17 +794,18 @@ class DatabaseContext:
\subsection
{
The contextlib module
\label
{
module-contextlib
}}
\subsection
{
The contextlib module
\label
{
module-contextlib
}}
The new
\module
{
contextlib
}
module provides some functions and a
The new
\module
{
contextlib
}
module provides some functions and a
decorator that are useful for writing context managers.
decorator that are useful for writing objects for use with the
'
\keyword
{
with
}
' statement.
The decorator is called
\function
{
contextmanager
}
, and lets you write
The decorator is called
\function
{
contextmanager
}
, and lets you write
a simple context manager as a generator
. The generator should yield
a simple context manager as a generator
function. The generator
exactly one value. The code up to the
\keyword
{
yield
}
will be
should yield exactly one value. The code up to the
\keyword
{
yield
}
executed as the
\method
{__
enter
__
()
}
method, and the value yielded
will be executed as the
\method
{__
enter
__
()
}
method, and the value
will be the method's return value that will get bound to the variabl
e
yielded will be the method's return value that will get bound to th
e
in the '
\keyword
{
with
}
' statement's
\keyword
{
as
}
clause, if any. The
variable in the '
\keyword
{
with
}
' statement's
\keyword
{
as
}
clause, if
code after the
\keyword
{
yield
}
will be executed in the
any. The
code after the
\keyword
{
yield
}
will be executed in the
\method
{__
exit
__
()
}
method. Any exception raised in the block
\method
{__
exit
__
()
}
method. Any exception raised in the block
will be
will be
raised by the
\keyword
{
yield
}
statement.
raised by the
\keyword
{
yield
}
statement.
Our database example from the previous section could be written
Our database example from the previous section could be written
using this decorator as:
using this decorator as:
...
@@ -832,8 +829,9 @@ with db_transaction(db) as cursor:
...
@@ -832,8 +829,9 @@ with db_transaction(db) as cursor:
...
...
\end{verbatim}
\end{verbatim}
You can also use this decorator to write the
\method
{__
context
__
()
}
method
You can also use this decorator to write the
\method
{__
context
__
()
}
for a class without creating a new class for the context:
method for a class without creating a new class to act as the context
manager:
\begin{verbatim}
\begin{verbatim}
class DatabaseConnection:
class DatabaseConnection:
...
@@ -851,8 +849,8 @@ class DatabaseConnection:
...
@@ -851,8 +849,8 @@ class DatabaseConnection:
\end{verbatim}
\end{verbatim}
There's a
\function
{
nested(
\var
{
mgr1
}
,
\var
{
mgr2
}
, ...)
}
manager
that
There's a
\function
{
nested(
\var
{
mgr1
}
,
\var
{
mgr2
}
, ...)
}
function
that
combines a number of context
manager
s so you don't need to write
combines a number of contexts so you don't need to write
nested '
\keyword
{
with
}
' statements. This example statement does two
nested '
\keyword
{
with
}
' statements. This example statement does two
things, starting a database transaction and acquiring a thread lock:
things, starting a database transaction and acquiring a thread lock:
...
@@ -862,7 +860,7 @@ with nested (db_transaction(db), lock) as (cursor, locked):
...
@@ -862,7 +860,7 @@ with nested (db_transaction(db), lock) as (cursor, locked):
...
...
\end{verbatim}
\end{verbatim}
Finally, the
\function
{
closing(
\var
{
object
}
)
}
context manager
Finally, the
\function
{
closing(
\var
{
object
}
)
}
function
returns
\var
{
object
}
so that it can be bound to a variable,
returns
\var
{
object
}
so that it can be bound to a variable,
and calls
\code
{
\var
{
object
}
.close()
}
at the end of the block.
and calls
\code
{
\var
{
object
}
.close()
}
at the end of the block.
...
@@ -880,8 +878,7 @@ with closing(urllib.urlopen('http://www.yahoo.com')) as f:
...
@@ -880,8 +878,7 @@ with closing(urllib.urlopen('http://www.yahoo.com')) as f:
\seepep
{
343
}{
The ``with'' statement
}{
PEP written by Guido van~Rossum
\seepep
{
343
}{
The ``with'' statement
}{
PEP written by Guido van~Rossum
and Nick Coghlan; implemented by Mike Bland, Guido van~Rossum, and
and Nick Coghlan; implemented by Mike Bland, Guido van~Rossum, and
Neal Norwitz. The PEP shows the code generated for a '
\keyword
{
with
}
'
Neal Norwitz. The PEP shows the code generated for a '
\keyword
{
with
}
'
statement, which can be helpful in learning how context managers
statement, which can be helpful in learning how the statement works.
}
work.
}
\seeurl
{
../lib/module-contextlib.html
}{
The documentation
\seeurl
{
../lib/module-contextlib.html
}{
The documentation
for the
\module
{
contextlib
}
module.
}
for the
\module
{
contextlib
}
module.
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment