    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: A Lifetime In Python</title>
        <link>https://members.accu.org/index.php/articles/2250</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #133 - June 2016 </span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c362/">o133</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-362/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+362/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;A Lifetime In Python</h1>
<p><strong>Author:</strong>&nbsp;Martin Moene</p>
<p>
<strong>Date:</strong> 05 June 2016 14:28:55 +01:00 or Sun, 05 June 2016 14:28:55 +01:00</p>
<p><strong>Summary:</strong>&nbsp;Resource management is important in any language. Steve Love demonstrates how to use context managers in Python.</p>
<p><strong>Body:</strong>&nbsp;<p>Variables in Python generally have a lifetime of their own. Or rather, the Python runtime interpreter handles object lifetime with automated garbage collection, leaving you to concentrate on more important things. Like <strong>Resource</strong> lifetime, which is much more interesting.</p>

<p>Python provides some facilities for handling the deterministic clean-up of certain objects, because sometimes itâ€™s necessary to know that it has happened at a specific point in a program. Things like closing file handles, releasing sockets, committing database changes â€“ the usual suspects.</p>

<p>In this article I will explore Pythonâ€™s tools for managing resources in a deterministic way, and demonstrate why itâ€™s easier and better to use them than to roll your own.</p>

<h2>Why you need it</h2>

<p>Python, like many other languages, indicates runtime errors with exceptions, which introduces <em>interesting</em> requirements on state. Exceptions are not necessarily visible directly in your code, either. You just have to know they might occur. Listing 1 shows a very basic (didactic) example.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
def addCustomerOrder( dbname, customer, order ):
  db = sqlite3.connect( dbname )               (1)
  db.execute( 'INSERT OR REPLACE INTO customers \
    (id, name) VAlUES (?, ?)', customer )      (2)
  db.execute( 'INSERT INTO orders (date, custid,\
    itemid, qty) VALUES (?, ?, ?, ?)', order ) (3)
  db.commit()                                  (4)
  db.close()                                   (5)
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<p>If an exception occurs between lines (1) and (3), the data wonâ€™t get committed to the database, the connection to the database will not be closed, and will therefore â€˜leakâ€™. This could be a <em>big</em> problem if this function or other functions like it get called frequently, say as the backend to a large web application. This wouldnâ€™t be the best way to implement this in any case, but the point is that the <code>db.execute()</code> statement can throw all kinds of exceptions.</p>

<p>You might then try to explicitly handle the exceptions, as shown in Listing  2, which ensures the database connection is closed even in the event of an exception. Closing a connection without explicitly committing changes will cause them to be rolled back.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
def addCustomerOrder( dbname, customer, order ):
  db = sqlite3.connect( dbname )
  try:
    db.execute( 'INSERT OR REPLACE \
      INTO customers \
      (id, name) VAlUES (?, ?)', customer )
    db.execute( 'INSERT INTO orders \
      (date, custid, itemid, qty) \
      VALUES (?, ?, ?, ?)', order )
    db.commit()
  finally:
    db.close()
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<p>It is a bit messy, and introduces some other questions such as: what happens if the <code>sqlite3.connect</code> method throws an exception? Do we need <em>another</em> outer-try block for that? Or expect clients of this function to wrap it in an exception handler?</p>

<p>Fortunately, Python has already asked, and answered some of these questions, with the Context Manager. This allows you to write the code shown in Listing 3.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
def addCustomerOrder( dbname, customer, order ):
  with  sqlite3.connect( dbname ) as db:
    db.execute( 'INSERT OR REPLACE \
      INTO customers \
      (id, name) VAlUES (?, ?)', customer )
    db.execute( 'INSERT INTO orders \
      (date, custid, itemid, qty) \
      VALUES (?, ?, ?, ?)', order )
  db.close()
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 3</td>
	</tr>
</table>

<p>The connection object from the <code>sqlite3</code> module implements the Context Manager protocol, which is invoked using the <code>with</code> statement. This introduces a block scope, and the Context Manager protocol gives objects that implement it a way of defining what happens when that scope is exited.</p>

<p>In the case of the connection object, that behaviour is to commit the (implicit, in this case) transaction if no errors occurred, or roll it back if an exception was raised in the block.</p>

<p>Note the explicit call to <code>db.close()</code> <em>outside</em> of the <code>with</code> statementâ€™s scope. The <em>only</em> behaviour defined for the connection object as Context Manager is to commit or roll back the transaction when the scope is exited. This construct doesnâ€™t say anything at all about the lifetime of the <code>db</code> object itself. It will (probably) be garbage collected at some indeterminate point in the future.</p>

<h2>You can do it too</h2>

<p>This customer database library might have several functions associated with it, perhaps including facilities to retrieve or update customer details, report orders and so on. Perhaps itâ€™s better represented as a type, exposing an interface that captures those needs. See Listing 4 for an example.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
class Customers( object ):
  def __init__( self, dbname ):
    self.db = sqlite3.connect( dbname )

  def close( self ):
    self.db.close()

  def addCustomerOrder( self, customer, order ):
    self.db.execute( 'INSERT OR REPLACE \
      INTO customers (id, name) \
      VAlUES (?, ?)', customer )
    self.db.execute( 'INSERT INTO orders \
      (date, custid, itemid, qty) \
      VALUES (?, ?, ?, ?)', order )

  # Other methods...

with Customers( dbname ) as db:
    db.addCustomerOrder( customer, order )
db.close()
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 4</td>
	</tr>
</table>

<p>Unfortunately, the line containing the <code>with</code> statement provokes an error similar to this:</p>

<pre class="programlisting">
    File &quot;customerdb.py&quot;, line 21, in &lt;module&gt;
      with Customers( dbname ) as db:
  AttributeError: __exit__</pre>

<p>You canâ€™t use <code>with</code> on just any type you create. Itâ€™s not a magic wand, either: the changes wonâ€™t get committed to the database if <code>commit()</code> is not called! However, the Context Manager facility isnâ€™t limited to just those types in the Python Standard Library. Itâ€™s implemented quite simply, as seen in Listing 5.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
class Customers( object ):
  def __init__( self, dbname ):
    self.dbname = dbname

  def __enter__( self ):
    self.db = sqlite3.connect( self.dbname )
    return self

  def __exit__( self, exc, val, trace ):
    if exc:
      self.db.rollback()
    else:
      self.db.commit()
    return None

  def close( self ):
    self.db.close()

  def addCustomerOrder( self, customer, order ):
    self.db.execute( 'INSERT OR REPLACE \
      INTO customers (id, name) \
      VAlUES (?, ?)', customer )
    self.db.execute( 'INSERT INTO \
      orders (date, custid, itemid, qty) \
      VALUES (?, ?, ?, ?)', order )

  # Other methods...

with Customers( dbname ) as db:
  db.addCustomerOrder( customer, order )
db.close()
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 5</td>
	</tr>
</table>

<p>The <code>__init__()</code> method is still there, but just saves the name away for later use. When the <code>with</code> statement is executed, it calls the objectâ€™s <code>__enter__()</code> method, and binds the return to the <code>as</code> clause if there is one: in this case, the <code>db</code> variable. The main content of the original construction method has been moved to the <code>__enter__()</code> method. Lastly, when the <code>with</code> statement block scope is exited, the <code>__exit__()</code> method of the managed object is called. If no exceptions occurred in the block, then the three arguments to <code>__exit__()</code> will be <code>None</code>. If an exception <em>did</em> occur, then they are populated with the type, value and stack trace object associated with the exception. This implementation essentially mimics the behaviour of the sqlite3 connection object, and rolls back if an exception occurred.</p>

<p>Returning a false-value indicates to the calling code that any exception that occurred inside the <code>with</code> block should be re-raised. Returning <code>None</code> counts â€“ and is only explicitly specified here for the purposes of explaining it. A Python function with no return statement is implicitly <code>None</code>. Returning a true-value indicates that any such exception should be suppressed.</p>

<table class="sidebartable">
	<tr>
		<td class="title">Object vs. Resource Lifetime</td>
	</tr>	
	<tr>
		<td>
			<table class="journaltable">
				<tr>
					<td>
						<p>These two concepts are frequently, and mistakenly, used interchangeably. The lifetime of an object is the time between its creation and its destruction, which is usually the point at which its memory is freed. The lifetime of the resource is tied to neither of those things, although itâ€™s very often sensible to associate the object with its resource when the object is created (i.e. in its <code>__init__()</code> method). You cannot know, for all intents and purposes, when the <em>object</em> lifetime ends, but you <em>can</em> know â€“ and can control â€“ when the <em>resource</em> lifetime ends. Pythonâ€™s Context Manager types and the associated <code>with</code> statement give you that control.</p>
						
						<p>You may have heard that Python objects can have a destructor â€“ the <code>__del__()</code> method. This special method is called when the object is garbage collected, and it allows you to perform a limited amount of last-chance cleanup. A common misapprehension is that invoking del thing will call the <code>__del__()</code> method on <code>thing</code> if itâ€™s defined. It wonâ€™t.</p>
					</td>
				</tr>
			</table>
		</td>
	</tr>

</table>

<h2>Consistent convenience</h2>

<p>Having to explicitly close the connection <em>after</em> the block has exited is a bit of a wart. We could decide that our own implementation of the <code>__exit__()</code> method invokes <code>close()</code> on the connection object having either committed or rolled back the changes, but there is a better way.</p>

<p>The <code>contextlib</code> module in the Python Standard Library provides some convenient utilities to help with exactly this, including the <code>closing</code> function, used like this:</p>

<pre class="programlisting">
  from contextlib import closing
  with closing( Customers( dbname ) ) as db:
    db.addCustomerOrder( customer, order )</pre>
	
<p>It will automatically call <code>close()</code> on the object to which itâ€™s bound when the block scope is exited.</p>

<p>Python File objects also have a Context Manager interface, and can be used in a <code>with</code> statement too. However, <em>their</em> behaviour on exit <em>is</em> to close the file, so you donâ€™t need to use the closing utility for file objects in Python.</p>

<pre class="programlisting">
  with open( filename ) as f:
    contents = f.read()</pre>
	
<p>So much for consistency! Itâ€™s a little odd having to know the internal behaviour of a given typeâ€™s Context Manager implementation (and the documentation isnâ€™t <em>always</em> clear on which types in the Standard Library <em>are</em> Context Managers), but sometimes the price of convenience is a little loss of consistency.</p>

<p>To reiterate the point about lifetime, even though the connection and file objects in the previous two examples have been closed, the lifetimes of the <em>objects</em> has not been affected.</p>

<h2>When one isnâ€™t enough</h2>

<p>Sometimes itâ€™s useful to associate several resources with a single Context Manager block. Suppose we want to be able to import a load of customer order data from a file into the database using the facility weâ€™ve already made.</p>

<p>In Python 3.1 and later, this can be achieved like this:</p>

<pre class="programlisting">
  with closing( Customers( dbname ) ) as db,  \
    open( 'orders.csv' ) as data:
    for line in data:
      db.addCustomerOrder( parseOrderData( line ) )</pre>
	  
<p>If youâ€™re stuck using a version of Python earlier than that, you have to nest the blocks like this:</p>

<pre class="programlisting">
with closing( Customers( dbname ) ) as db:
  with open( 'orders.csv' ) as data:
    for line in data:
      db.addCustomerOrder( parseOrderData( line ) )</pre>
	  
<p>Either syntax gets unwieldy very quickly with more than two or three managed objects. One approach to this is to create a new type that implements the Context Manager protocol, and wraps up multiple resources, leaving the calling code with a single with statement on the wrapping type, as shown in Listing 6.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
class WrappedResources( object ):
  def __init__( self, dbname, filename ):
    self.dbname = dbname
    self.filename = filename

  def __enter__( self ):
    self.db = sqlite3.connect( self.dbname )
    self.data = open( self.filename )

  def __exit__( self, *exceptions ):
    if not any( exceptions ): self.db.commit()

  def close( self ):
    self.data.close()
    self.db.close()

  def addCustomerOrder( customer, order ):
    pass # do the right thing here

with closing( WrappedResource( dbname, fname ) ) \
  as res:
  for line in res.data:
    res.addCustomerOrder( parseOrderData( line ) )
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 6</td>
	</tr>
</table>

<p>That really is a little clunky, however you look at it, since itâ€™s fairly obvious that the class has multiple responsibilities, and exposes the managed objects publicly, amongst other things. There are better ways to achieve this, and we will return to this shortly.</p>

<h2>Common cause</h2>

<p>Having implemented a (basic) facility to import data from a file to our database, we might like to extend the idea and optionally read from the standard input stream. A simple protocol for this might be to read <code>sys.stdin</code> if no filename is given, leading to code like this:</p>

<pre class="programlisting">
  with options.filename and \
    open( options.filename ) or sys.stdin as input:
    # do something with the data</pre>
	
<p>Thatâ€™s all very well, but is a little arcane, and <em>closing</em> the standard input handle when it completes might be considered bad manners. You could go to all the bother of reinstating the standard input handle, or redirecting it some other way, but that too seems more complicated than what is required.</p>

<p>Pythonâ€™s <code>contextlib</code> module has another handy utility to allow you to use a generator function as a Context Manager, without going to the trouble of creating a custom class to implement the protocol. It is used to <strong>decorate</strong> a function, which must <code>yield</code> exactly one value to be bound to the <code>as</code> clause of a <code>with</code> statement. Actions to perform when the block is entered are put before the <code>yield</code>, actions to perform when the block is exited are put after the <code>yield</code>. It follows the basic pattern shown in Listing 7:</p>
<p style="margin-left:1em">(1) will be called when the <code>with</code> statement is entered. Itâ€™s the equivalent of the <code>__enter__()</code> method</p>
<p style="margin-left:1em">(2) will be called when the block is exited. Itâ€™s the equivalent of the <code>__exit__()</code> method</p>
<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
import contextlib

@contextlib.contextmanager
def simpleContext():
  doPreActionsHere()          (1)
  yield managed_object
  doPostActionsHere()         (2)
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 7</td>
	</tr>
</table>



<p>This allows us to define a couple of factory functions for our inputs, as shown in Listing 8.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
import contextlib

def openFilename():
  return open( options.filename )

@contextlib.contextmanager
def openStdIn():
  yield sys.stdin

opener = options.filename and openFilename \
  or openStdIn
with opener() as f:
  pass   # Use f
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 8</td>
	</tr>
</table>

<p>Since opening a â€˜realâ€™ file returns an object that is already a Context Manager, the function for that isnâ€™t decorated. Likewise, since we do <em>not</em> want to perform any action on the <code>sys.stdin</code> object on exit, that function has no behaviour after the <code>yield</code>.</p>

<p>It should be clear that the Context Manager protocol is more general purpose than just for performing some clean-up action when leaving a scope. Exception safety is the primary purpose of the Context Managers, but the <code>__enter__()</code> and <code>__exit__()</code> methods can contain any arbitrary behaviour, just as the decorated function can perform any actions before and after the <code>yield</code> statement. Examples include tracking function entry and exit, and logging contexts such as those Chris Oldwood shows in C# [<a href="Love.xml#[Oldwood]">Oldwood</a>].</p>

<h2>Many and varied</h2>

<p>As previously mentioned, itâ€™s sometimes necessary to manage multiple resources within a single block. Python 3.1 and later support this by allowing multiple Context Manager objects to be declared in a single <code>with</code> statement, but this becomes cluttered and unmanageable quickly. You can, as we demonstrated, create your own Context Manager type, but that too can be less than ideal. Once again, Python 3.3 answers the question with another <code>contextlib</code> utility, the <code>ExitStack</code>.</p>

<p>It manages multiple Context Manager objects, and allows you to declare them in a tidy (and indentation-saving) manner. See Listing 9.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
with contextlib.ExitStack() as stack:
  f = stack.enter_context( open( \
    options.filename ) )
  db = stack.enter_context( sqlite3.connect( \
    options.dbname ) )
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 9</td>
	</tr>
</table>

<p>Objects have their <code>__exit__()</code> method called, in the reverse order to which they were added, when the block is exited.</p>

<p>The <code>ExitStack</code> can manage a runtime-defined collection of context managers, such as this example taken directly from the Python 3.4 documentation [<a href="Love.xml#[Python]">Python</a>]:</p>

<pre class="programlisting">
  with ExitStack() as stack:
    files = [ stack.enter_context( open( fname ) ) \
    for fname in filenames ]
    # All opened files will automatically be closed
    # at the end of the with statement, even if
    # attempts to open files later in the list raise
    # an exception</pre>

<h2>Conclusion</h2>

<p>Pythonâ€™s Context Managers are a convenient and easy-to-use way of managing Resource Lifetimes, but their utility goes beyond that, due to the flexible way they are provided. The basic idea is not a new one â€“ even in Python, where it was first introduced in version 2.5 â€“ but some of these facilities are only available in later versions of the language. The examples given here were tested using Python 3.4.</p>

<p>Exception safety facilities like the Python Context Manager are common to many languages that feature the use of exceptions to indicate errors, because this introduces the need for some local clean-up in the presence of what is (in effect) a non-local jump in the code. They are, however, useful for things beyond this need, and Python provides several useful utilities to help manage the complexity this brings.</p>

<h2>References</h2>

<p class="bibliomixed"><a id="[Python]"></a>[Python] Python 3.4 Documentation. <a href="https://docs.python.org/3.4/library/contextlib.html">https://docs.python.org/3.4/library/contextlib.html</a></p>

<p class="bibliomixed"><a id="[Oldwood]"></a>[Oldwood] Oldwood, Chris. Causality, <a href="http://chrisoldwood.com/articles/causality.html">http://chrisoldwood.com/articles/causality.html</a></p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
