[code.view]

[top] / python / PyMOTW / docs / contextlib / index.html


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>contextlib – Context manager utilities &mdash; Python Module of the Week</title>
    <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '1.132',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <link rel="author" title="About these documents" href="../about.html" />
    <link rel="top" title="Python Module of the Week" href="../index.html" />
    <link rel="up" title="Python Runtime Services" href="../runtime_services.html" />
    <link rel="next" title="gc – Garbage Collector" href="../gc/index.html" />
    <link rel="prev" title="atexit – Call functions when a program is closing down" href="../atexit/index.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="../gc/index.html" title="gc – Garbage Collector"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="../atexit/index.html" title="atexit – Call functions when a program is closing down"
             accesskey="P">previous</a> |</li>
        <li><a href="../contents.html">PyMOTW</a> &raquo;</li>
          <li><a href="../runtime_services.html" accesskey="U">Python Runtime Services</a> &raquo;</li> 
      </ul>
    </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">contextlib &#8211; Context manager utilities</a><ul>
<li><a class="reference internal" href="#context-manager-api">Context Manager API</a></li>
<li><a class="reference internal" href="#from-generator-to-context-manager">From Generator to Context Manager</a></li>
<li><a class="reference internal" href="#nesting-contexts">Nesting Contexts</a></li>
<li><a class="reference internal" href="#closing-open-handles">Closing Open Handles</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="../atexit/index.html"
                        title="previous chapter">atexit &#8211; Call functions when a program is closing down</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="../gc/index.html"
                        title="next chapter">gc &#8211; Garbage Collector</a></p>
  <h3>This Page</h3>
  <ul class="this-page-menu">
    <li><a href="../_sources/contextlib/index.txt"
           rel="nofollow">Show Source</a></li>
  </ul>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" size="18" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="module-contextlib">
<span id="contextlib-context-manager-utilities"></span><h1>contextlib &#8211; Context manager utilities<a class="headerlink" href="#module-contextlib" title="Permalink to this headline">¶</a></h1>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Purpose:</th><td class="field-body">Utilities for creating and working with context managers.</td>
</tr>
<tr class="field"><th class="field-name">Python Version:</th><td class="field-body">2.5 and later</td>
</tr>
</tbody>
</table>
<p>The <a class="reference internal" href="#module-contextlib" title="contextlib: Utilities for creating and working with context managers."><tt class="xref py py-mod docutils literal"><span class="pre">contextlib</span></tt></a> module contains utilities for working with
context managers and the <strong class="command">with</strong> statement.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Context managers are tied to the <strong class="command">with</strong> statement. Since
<strong class="command">with</strong> is officially part of Python 2.6, you have to import it
from <tt class="xref py py-mod docutils literal"><span class="pre">__future__</span></tt> before using contextlib in Python 2.5.</p>
</div>
<div class="section" id="context-manager-api">
<h2>Context Manager API<a class="headerlink" href="#context-manager-api" title="Permalink to this headline">¶</a></h2>
<p>A <em>context manager</em> is responsible for a resource within a code block,
possibly creating it when the block is entered and then cleaning it up
after the block is exited.  For example, files support the context
manager API to make it easy to ensure they are closed after all
reading or writing is done.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">&#39;/tmp/pymotw.txt&#39;</span><span class="p">,</span> <span class="s">&#39;wt&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
    <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;contents go here&#39;</span><span class="p">)</span>
<span class="c"># file is automatically closed</span>
</pre></div>
</div>
<p>A context manager is enabled by the <strong class="command">with</strong> statement, and the
API involves two methods.  The <tt class="xref py py-func docutils literal"><span class="pre">__enter__()</span></tt> method is run when
execution flow enters the code block inside the <strong class="command">with</strong>.  It
returns an object to be used within the context.  When execution flow
leaves the <strong class="command">with</strong> block, the <tt class="xref py py-func docutils literal"><span class="pre">__exit__()</span></tt> method of the
context manager is called to clean up any resources being used.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Context</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;__init__()&#39;</span>

    <span class="k">def</span> <span class="nf">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;__enter__()&#39;</span>
        <span class="k">return</span> <span class="bp">self</span>
    
    <span class="k">def</span> <span class="nf">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_val</span><span class="p">,</span> <span class="n">exc_tb</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;__exit__()&#39;</span>
        
<span class="k">with</span> <span class="n">Context</span><span class="p">():</span>
    <span class="k">print</span> <span class="s">&#39;Doing work in the context&#39;</span>
</pre></div>
</div>
<p>Combining a context manager and the <strong class="command">with</strong> statement is a
more compact way of writing a <tt class="docutils literal"><span class="pre">try:finally</span></tt> block, since the context
manager&#8217;s <tt class="xref py py-func docutils literal"><span class="pre">__exit__()</span></tt> method is always called, even if an
exception is raised.</p>
<div class="highlight-python"><pre>$ python contextlib_api.py

__init__()
__enter__()
Doing work in the context
__exit__()</pre>
</div>
<p><tt class="xref py py-func docutils literal"><span class="pre">__enter__()</span></tt> can return any object to be associated with a name
specified in the <strong class="command">as</strong> clause of the <strong class="command">with</strong>
statement.  In this example, the <tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt> returns an object
that uses the open context.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">WithinContext</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;WithinContext.__init__(</span><span class="si">%s</span><span class="s">)&#39;</span> <span class="o">%</span> <span class="n">context</span>
        
    <span class="k">def</span> <span class="nf">do_something</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;WithinContext.do_something()&#39;</span>

    <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;WithinContext.__del__&#39;</span>
        

<span class="k">class</span> <span class="nc">Context</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;Context.__init__()&#39;</span>

    <span class="k">def</span> <span class="nf">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;Context.__enter__()&#39;</span>
        <span class="k">return</span> <span class="n">WithinContext</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_val</span><span class="p">,</span> <span class="n">exc_tb</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;Context.__exit__()&#39;</span>
    
<span class="k">with</span> <span class="n">Context</span><span class="p">()</span> <span class="k">as</span> <span class="n">c</span><span class="p">:</span>
    <span class="n">c</span><span class="o">.</span><span class="n">do_something</span><span class="p">()</span>
</pre></div>
</div>
<p>It can be a little confusing, but the value associated with the
variable <tt class="xref py py-data docutils literal"><span class="pre">c</span></tt> is the object returned by <tt class="xref py py-func docutils literal"><span class="pre">__enter__()</span></tt> and
<em>not</em> the <tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt> instance created in the <strong class="command">with</strong>
statement.</p>
<div class="highlight-python"><pre>$ python contextlib_api_other_object.py

Context.__init__()
Context.__enter__()
WithinContext.__init__(&lt;__main__.Context object at 0x100459a50&gt;)
WithinContext.do_something()
Context.__exit__()
WithinContext.__del__</pre>
</div>
<p>The <tt class="xref py py-func docutils literal"><span class="pre">__exit__()</span></tt> method receives arguments containing details of
any exception raised in the <strong class="command">with</strong> block.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Context</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">handle_error</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;__init__(</span><span class="si">%s</span><span class="s">)&#39;</span> <span class="o">%</span> <span class="n">handle_error</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">handle_error</span> <span class="o">=</span> <span class="n">handle_error</span>

    <span class="k">def</span> <span class="nf">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;__enter__()&#39;</span>
        <span class="k">return</span> <span class="bp">self</span>
    
    <span class="k">def</span> <span class="nf">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_val</span><span class="p">,</span> <span class="n">exc_tb</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;__exit__(</span><span class="si">%s</span><span class="s">, </span><span class="si">%s</span><span class="s">, </span><span class="si">%s</span><span class="s">)&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_val</span><span class="p">,</span> <span class="n">exc_tb</span><span class="p">)</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">handle_error</span>
        
<span class="k">with</span> <span class="n">Context</span><span class="p">(</span><span class="bp">True</span><span class="p">):</span>
    <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&#39;error message handled&#39;</span><span class="p">)</span>

<span class="k">print</span>

<span class="k">with</span> <span class="n">Context</span><span class="p">(</span><span class="bp">False</span><span class="p">):</span>
    <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&#39;error message propagated&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>If the context manager can handle the exception, <tt class="xref py py-func docutils literal"><span class="pre">__exit__()</span></tt>
should return a true value to indicate that the exception does not
need to be propagated.  Returning false causes the exception to be
re-raised after <tt class="xref py py-func docutils literal"><span class="pre">__exit__()</span></tt> returns.</p>
<div class="highlight-python"><pre>$ python contextlib_api_error.py

__init__(True)
__enter__()
__exit__(&lt;type 'exceptions.RuntimeError'&gt;, error message handled, &lt;traceback object at 0x100463248&gt;)

__init__(False)
__enter__()
__exit__(&lt;type 'exceptions.RuntimeError'&gt;, error message propagated, &lt;traceback object at 0x1004632d8&gt;)
Traceback (most recent call last):
  File "contextlib_api_error.py", line 30, in &lt;module&gt;
    raise RuntimeError('error message propagated')
RuntimeError: error message propagated</pre>
</div>
</div>
<div class="section" id="from-generator-to-context-manager">
<h2>From Generator to Context Manager<a class="headerlink" href="#from-generator-to-context-manager" title="Permalink to this headline">¶</a></h2>
<p>Creating context managers the traditional way, by writing a class with
<tt class="xref py py-func docutils literal"><span class="pre">__enter__()</span></tt> and <tt class="xref py py-func docutils literal"><span class="pre">__exit__()</span></tt> methods, is not
difficult. But sometimes it is more overhead than you need just to
manage a trivial bit of context. In those sorts of situations, you can
use the <tt class="xref py py-func docutils literal"><span class="pre">contextmanager()</span></tt> decorator to convert a generator
function into a context manager.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">contextlib</span>

<span class="nd">@contextlib.contextmanager</span>
<span class="k">def</span> <span class="nf">make_context</span><span class="p">():</span>
    <span class="k">print</span> <span class="s">&#39;  entering&#39;</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">yield</span> <span class="p">{}</span>
    <span class="k">except</span> <span class="ne">RuntimeError</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span>
        <span class="k">print</span> <span class="s">&#39;  ERROR:&#39;</span><span class="p">,</span> <span class="n">err</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="k">print</span> <span class="s">&#39;  exiting&#39;</span>

<span class="k">print</span> <span class="s">&#39;Normal:&#39;</span>
<span class="k">with</span> <span class="n">make_context</span><span class="p">()</span> <span class="k">as</span> <span class="n">value</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&#39;  inside with statement:&#39;</span><span class="p">,</span> <span class="n">value</span>

<span class="k">print</span>
<span class="k">print</span> <span class="s">&#39;Handled error:&#39;</span>
<span class="k">with</span> <span class="n">make_context</span><span class="p">()</span> <span class="k">as</span> <span class="n">value</span><span class="p">:</span>
    <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&#39;showing example of handling an error&#39;</span><span class="p">)</span>

<span class="k">print</span>
<span class="k">print</span> <span class="s">&#39;Unhandled error:&#39;</span>
<span class="k">with</span> <span class="n">make_context</span><span class="p">()</span> <span class="k">as</span> <span class="n">value</span><span class="p">:</span>
    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s">&#39;this exception is not handled&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>The generator should initialize the context, yield exactly one time,
then clean up the context. The value yielded, if any, is bound to the
variable in the <strong class="command">as</strong> clause of the <strong class="command">with</strong>
statement. Exceptions from within the <strong class="command">with</strong> block are
re-raised inside the generator, so they can be handled there.</p>
<div class="highlight-python"><pre>$ python contextlib_contextmanager.py

Normal:
  entering
  inside with statement: {}
  exiting

Handled error:
  entering
  ERROR: showing example of handling an error
  exiting

Unhandled error:
  entering
  exiting
Traceback (most recent call last):
  File "contextlib_contextmanager.py", line 34, in &lt;module&gt;
    raise ValueError('this exception is not handled')
ValueError: this exception is not handled</pre>
</div>
</div>
<div class="section" id="nesting-contexts">
<h2>Nesting Contexts<a class="headerlink" href="#nesting-contexts" title="Permalink to this headline">¶</a></h2>
<p>At times it is necessary to manage multiple contexts simultaneously
(such as when copying data between input and output file handles, for
example). It is possible to nest <strong class="command">with</strong> statements one inside
another. If the outer contexts do not need their own separate block,
though, this adds to the indention level without giving any real
benefit. Using <tt class="xref py py-func docutils literal"><span class="pre">nested()</span></tt> nests the contexts using a single
<strong class="command">with</strong> statement.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">contextlib</span>

<span class="nd">@contextlib.contextmanager</span>
<span class="k">def</span> <span class="nf">make_context</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
    <span class="k">print</span> <span class="s">&#39;entering:&#39;</span><span class="p">,</span> <span class="n">name</span>
    <span class="k">yield</span> <span class="n">name</span>
    <span class="k">print</span> <span class="s">&#39;exiting :&#39;</span><span class="p">,</span> <span class="n">name</span>

<span class="k">with</span> <span class="n">contextlib</span><span class="o">.</span><span class="n">nested</span><span class="p">(</span><span class="n">make_context</span><span class="p">(</span><span class="s">&#39;A&#39;</span><span class="p">),</span> <span class="n">make_context</span><span class="p">(</span><span class="s">&#39;B&#39;</span><span class="p">),</span> <span class="n">make_context</span><span class="p">(</span><span class="s">&#39;C&#39;</span><span class="p">))</span> <span class="k">as</span> <span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">B</span><span class="p">,</span> <span class="n">C</span><span class="p">):</span>
    <span class="k">print</span> <span class="s">&#39;inside with statement:&#39;</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="n">B</span><span class="p">,</span> <span class="n">C</span>
</pre></div>
</div>
<p>Notice that the contexts are exited in the reverse order in which they are
entered.</p>
<div class="highlight-python"><pre>$ python contextlib_nested.py

entering: A
entering: B
entering: C
inside with statement: A B C
exiting : C
exiting : B
exiting : A</pre>
</div>
<p>In Python 2.7 and later, <tt class="xref py py-func docutils literal"><span class="pre">nested()</span></tt> is deprecated because the
<strong class="command">with</strong> statement supports nesting directly.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">contextlib</span>

<span class="nd">@contextlib.contextmanager</span>
<span class="k">def</span> <span class="nf">make_context</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
    <span class="k">print</span> <span class="s">&#39;entering:&#39;</span><span class="p">,</span> <span class="n">name</span>
    <span class="k">yield</span> <span class="n">name</span>
    <span class="k">print</span> <span class="s">&#39;exiting :&#39;</span><span class="p">,</span> <span class="n">name</span>

<span class="k">with</span> <span class="n">make_context</span><span class="p">(</span><span class="s">&#39;A&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">A</span><span class="p">,</span> <span class="n">make_context</span><span class="p">(</span><span class="s">&#39;B&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">B</span><span class="p">,</span> <span class="n">make_context</span><span class="p">(</span><span class="s">&#39;C&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">C</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&#39;inside with statement:&#39;</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="n">B</span><span class="p">,</span> <span class="n">C</span>
</pre></div>
</div>
<p>Each context manager and optional <strong class="command">as</strong> clause are separated
by a comma (<tt class="docutils literal"><span class="pre">,</span></tt>).  The effect is similar to using <tt class="xref py py-func docutils literal"><span class="pre">nested()</span></tt>,
but avoids some of the edge-cases around error handling that
<tt class="xref py py-func docutils literal"><span class="pre">nested()</span></tt> could not implement correctly.</p>
<div class="highlight-python"><pre>$ python contextlib_nested_with.py

entering: A
entering: B
entering: C
inside with statement: A B C
exiting : C
exiting : B
exiting : A</pre>
</div>
</div>
<div class="section" id="closing-open-handles">
<h2>Closing Open Handles<a class="headerlink" href="#closing-open-handles" title="Permalink to this headline">¶</a></h2>
<p>The <tt class="xref py py-class docutils literal"><span class="pre">file</span></tt> class supports the context manager API directly, but
some other objects that represent open handles do not. The example
given in the standard library documentation for <a class="reference internal" href="#module-contextlib" title="contextlib: Utilities for creating and working with context managers."><tt class="xref py py-mod docutils literal"><span class="pre">contextlib</span></tt></a> is
the object returned from <tt class="xref py py-func docutils literal"><span class="pre">urllib.urlopen()</span></tt>.  There are other
legacy classes that use a <tt class="xref py py-func docutils literal"><span class="pre">close()</span></tt> method but do not support the
context manager API. To ensure that a handle is closed, use
<tt class="xref py py-func docutils literal"><span class="pre">closing()</span></tt> to create a context manager for it.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">contextlib</span>

<span class="k">class</span> <span class="nc">Door</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;  __init__()&#39;</span>
    <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&#39;  close()&#39;</span>

<span class="k">print</span> <span class="s">&#39;Normal Example:&#39;</span>
<span class="k">with</span> <span class="n">contextlib</span><span class="o">.</span><span class="n">closing</span><span class="p">(</span><span class="n">Door</span><span class="p">())</span> <span class="k">as</span> <span class="n">door</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&#39;  inside with statement&#39;</span>

<span class="k">print</span>
<span class="k">print</span> <span class="s">&#39;Error handling example:&#39;</span>
<span class="k">try</span><span class="p">:</span>
    <span class="k">with</span> <span class="n">contextlib</span><span class="o">.</span><span class="n">closing</span><span class="p">(</span><span class="n">Door</span><span class="p">())</span> <span class="k">as</span> <span class="n">door</span><span class="p">:</span>
        <span class="k">print</span> <span class="s">&#39;  raising from inside with statement&#39;</span>
        <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">&#39;error message&#39;</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&#39;  Had an error:&#39;</span><span class="p">,</span> <span class="n">err</span>
</pre></div>
</div>
<p>The handle is closed whether there is an error in the <strong class="command">with</strong>
block or not.</p>
<div class="highlight-python"><pre>$ python contextlib_closing.py

Normal Example:
  __init__()
  inside with statement
  close()

Error handling example:
  __init__()
  raising from inside with statement
  close()
  Had an error: error message</pre>
</div>
<div class="admonition-see-also admonition seealso">
<p class="first admonition-title">See also</p>
<dl class="last docutils">
<dt><a class="reference external" href="http://docs.python.org/library/contextlib.html">contextlib</a></dt>
<dd>The standard library documentation for this module.</dd>
<dt><span class="target" id="index-0"></span><a class="pep reference external" href="http://www.python.org/dev/peps/pep-0343"><strong>PEP 343</strong></a></dt>
<dd>The <strong class="command">with</strong> statement.</dd>
<dt><a class="reference external" href="http://docs.python.org/library/stdtypes.html#typecontextmanager">Context Manager Types</a></dt>
<dd>Description of the context manager API from the standard library documentation.</dd>
<dt><a class="reference external" href="http://docs.python.org/reference/datamodel.html#context-managers">With Statement Context Managers</a></dt>
<dd>Description of the context manager API from the Python Reference Guide.</dd>
</dl>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="../gc/index.html" title="gc – Garbage Collector"
             >next</a> |</li>
        <li class="right" >
          <a href="../atexit/index.html" title="atexit – Call functions when a program is closing down"
             >previous</a> |</li>
        <li><a href="../contents.html">PyMOTW</a> &raquo;</li>
          <li><a href="../runtime_services.html" >Python Runtime Services</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; Copyright Doug Hellmann.
      Last updated on Oct 24, 2010.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.

    <br/><a href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/" rel="license"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png"/></a>
    
    </div>
  </body>
</html>

[top] / python / PyMOTW / docs / contextlib / index.html

contact | logmethods.com