<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>learning python &#187; python</title>
	<atom:link href="http://www.learningpython.com/category/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.learningpython.com</link>
	<description>one man's journey into python...</description>
	<lastBuildDate>Wed, 21 Sep 2011 03:08:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>New Belorussian/Belarusian Translation</title>
		<link>http://www.learningpython.com/2011/04/21/newbelorussian/</link>
		<comments>http://www.learningpython.com/2011/04/21/newbelorussian/#comments</comments>
		<pubDate>Thu, 21 Apr 2011 14:21:03 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[Translation]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=224</guid>
		<description><![CDATA[Hey everyone, just a quick note to let you know that Bohdan has translated the Creating a GUI using PyGTK and Glade tutorial in to Belorussian/Belarusian. You can view the translation here: Belorussian translation. Many thanks to Bohdan and all the other who have translated some of these tutorials over the years.]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2011%2F04%2F21%2Fnewbelorussian%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2011%2F04%2F21%2Fnewbelorussian%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Hey everyone, just a quick note to let you know that Bohdan has translated the <a href="http://www.learningpython.com/2006/05/07/creating-a-gui-using-pygtk-and-glade/">Creating a GUI using PyGTK and Glade</a> tutorial in to Belorussian/Belarusian.  You can view the translation here: <a href="http://www.webhostinghub.com/support/creating-a-gui-using-pygtk-and-glade-be">Belorussian translation</a>.</p>
<p>Many thanks to Bohdan and all the other who have translated some of these tutorials over the years.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2011/04/21/newbelorussian/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Future Statements to Prepare for the Future</title>
		<link>http://www.learningpython.com/2010/09/22/using-future-statements-to-prepare-for-the-future/</link>
		<comments>http://www.learningpython.com/2010/09/22/using-future-statements-to-prepare-for-the-future/#comments</comments>
		<pubDate>Thu, 23 Sep 2010 01:43:21 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[Python Magazine]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=214</guid>
		<description><![CDATA[Note: This article was first published the June 2008 issue of Python Magazine Mark Mruss With the release of Python 3.0 only a few months away many Python programmers have visions of compatibility problems dancing in their heads. This article will introduce the concept of future statements including two future statements that you can use [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F09%2F22%2Fusing-future-statements-to-prepare-for-the-future%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F09%2F22%2Fusing-future-statements-to-prepare-for-the-future%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Note: This article was first published the <a href="http://www.pythonmagazine.com/c/issue/view/70">June 2008</a> issue of <a href="http://www.pythonmagazine.com/">Python Magazine</a></p>
<p><strong>Mark Mruss</strong></p>
<p>With the release of Python 3.0 only a few months away many Python programmers have visions of compatibility problems dancing in their heads. This article will introduce the concept of future statements including two future statements that you can use to help prepare your code for version 3.0.</p>
<h2>Introduction</h2>
<p>Python 3.0 (or Python 3000 as many people know it) is something that many Python programmers have started thinking about. Besides being the next major version of our beloved programming language, version 3.0 of Python will break backwards compatibility with the current 2.0 branch of Python. This means that a some of the code that you are writing right now in Python 2.X won&#8217;t immediately work in Python 3.0. Since Python 3.0 has a scheduled release date of September 2008 <a href="http://www.python.org/dev/peps/pep-0361/">[1]</a> now may be a good time to start thinking about future migration.</p>
<p>Of course there&#8217;s no reason to be alarmed yet. Guido, himself, has said that there is no rush to switch over to Python 3.0. <a href="http://www.python.org/doc/essays/ppt/pycon2008/Py3kAndYou.pdf">[2]</a> According to his PyCon 2008 essay &#8220;Python 3000 and You&#8221; you should switch when the following are true: &#8220;1. You&#8217;re ready 2. All your dependencies have been ported.&#8221; <a href="http://www.python.org/doc/essays/ppt/pycon2008/Py3kAndYou.pdf">[3]</a></p>
<p>In the same essay Guido also says that Python programmers should be prepared and that they should &#8220;start writing future-proof&#8221; code for 2.5&#8243; <a href="http://www.python.org/doc/essays/ppt/pycon2008/Py3kAndYou.pdf">[4]</a> In this sprit, this article will introduce &#8220;future statements&#8221; and two ways that you can use them <em>now</em> in order to make the migration process from the Python 2.0 branch to the Python 3.0 branch as smooth as possible.</p>
<p>The rest of this article, and the examples within, will assume that you are working with Python 2.5.<br />
<span id="more-214"></span></p>
<h2>Import the Future</h2>
<p>A very important step in getting your code ready for Python 3.0 is to make use of the __future__ module. The __future__ module allows you to both import changes that are going to be made in future version of Python and use them in your current version of Python.</p>
<p>For example, if feature X is slated to change to feature Y in a future version of Python, there is a chance that it may be supported by the __future__ module. If feature Y is supported by the __future__ module, you can import feature Y from the __future__ module in the version of Python that is still using feature X. This means that instead of having to alter your code when feature X is deprecated and feature Y is implemented, you can write your code now using feature Y and not worry about when the switch will occur.</p>
<h2>Future Statements</h2>
<p>When you use the __future__ module you will be creating future statements.  Future statements, and the purpose of the __future__ module are defined quite well in the Python documentation:</p>
<p>&#8220;A future statement is a directive to the compiler that a particular module should be compiled using syntax or semantics that will be available in a specified future release of Python. The future statement is intended to ease migration to future versions of Python that introduce incompatible changes to the language. It allows use of the new features on a per-module basis before the release in which the feature becomes standard.&#8221; <a href="http://docs.python.org/ref/future.html">[5]</a></p>
<p>Future statements are what will import the new features from the __future__ module. Future statements must be at the top of your module; only comments, blank lines, or other future statements can be located before them.</p>
<p>Let&#8217;s take a look at a future statement that will let us work with the changes that will happen to the division operation (explained later):</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">__future__ </span><span class="hl-reserved">import </span><span class="hl-identifier">division</span></pre></div></div>
<p>This will change the implementation of the division operation, in whatever module the future statement occurs, from its current integer form to its future float form.</p>
<h2>Floating Division</h2>
<p>Now that we know what a future statement is and how to use the __future__ module, let&#8217;s look at the changes that will be made to the division operation. In the current branch of Python the division operation can be somewhat confusing. It can be integer division (returning the floor of the division, i.e. only the integer quotient) or floating point division (returning the result as a float including the remainder).</p>
<p>Confusion within the current state of Python&#8217;s division operation can be seen in the following example:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">print </span><span class="hl-number">3</span><span class="hl-default">/</span><span class="hl-number">2
</span><span class="hl-reserved">print </span><span class="hl-number">3</span><span class="hl-default">/</span><span class="hl-number">2.0</span></pre></div></div>
<p>This results in:<br />
<code><br />
1<br />
1.5<br />
</code></p>
<p>Here Python is looking at the type of the operands in the operation. If they are both of type int, integer division will be performed as shown in the first result. If one (or both) of the values is a float, the operation will return a float that will include the remainder (if there is one).</p>
<p>Note that division of this sort (where the result type is dependent on the operands) is common in other programming languages.</p>
<p>While the correct type of division to be performed may be obvious when literal numbers are being used, unexpected results can occur when you are working with variables whose type may be unknown:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">divide_by_three</span><span class="hl-brackets">(</span><span class="hl-identifier">value</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-number">3</span><span class="hl-default">/</span><span class="hl-identifier">value</span></pre></div></div>
<p>This will result in both integer and float return values depending on the type of &#8216;value&#8217;.</p>
<p>As a result of this confusion, in Python 3.0 changes are being made to what the division operation returns. All division using a single slash (/) will return a floating point number including the remainder. In order to perform integer division, you will need to use two slashes (//). The type of division performed now depends on the number of slashes used and not the type of the operands. The only gotcha to be aware of is that if one of the operands in the  division operation is a float, the return value will also be a float with 0 as the remainder.</p>
<p>Listing 1 uses a future statement to import the changes to the division operation and replicates our previous division test. If you were to run the code found in Listing 1 the output would be as follows:<br />
<code><br />
1.5<br />
1.0<br />
</code></p>
<p>If you are writing code where you perform division of any sort, I&#8217;d suggest importing division from __future__ so that when the move to Python 3.0 occurs, you won&#8217;t find yourself with any strange results.</p>
<p>Note that the // division operation has been in Python since version 2.2 so you can already use it without importing division from __future__. Importing division from __future__ changes the functionality of the / division operation.</p>
<h2>The future of Imports</h2>
<p>In Python 3.0 all imports will be absolute.  This means that when you perform an import, you will import &#8220;a module or package reachable from sys.path.&#8221;<a href="http://www.python.org/dev/peps/pep-0328/#rationale-for-absolute-imports">[6]</a> While at first glance this may seem to make importing local modules impossible, it is important to remember that when you launch a Python script file directly, the directory where that script file is located will be added to the start of sys.path in position 0.</p>
<p>To illustrate the reason for the change to absolute imports, let&#8217;s take a look at a silly example. Let&#8217;s say we had a project that used a tokenizer package using the directory tree shown in Figure 1 where string.py is a helper module (with an unfortunate name) that the parse.py module needs to use.</p>
<p>In this example my_proj.py won&#8217;t do anything besides import the tokenizer package and create an instance of a Parse object:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">tokenizer

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">'</span><span class="hl-string">__main__</span><span class="hl-quotes">'</span><span class="hl-default">:
    </span><span class="hl-identifier">parser</span><span class="hl-default"> = </span><span class="hl-identifier">tokenizer</span><span class="hl-default">.</span><span class="hl-identifier">Parse</span><span class="hl-brackets">()</span></pre></div></div>
<p>The __init__.py modules in the tokenizer package imports the Parse class from the parse module. This is done so that the Parse class can be accessed as tokenizer.Parse as opposed to tokenizer.parse.Parse:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">parse </span><span class="hl-reserved">import </span><span class="hl-identifier">Parse</span></pre></div></div>
<p>Finally, parse.py is where all of the magic happens:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">string

</span><span class="hl-reserved">class </span><span class="hl-identifier">Parse</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">print</span><span class="hl-brackets">(</span><span class="hl-identifier">string</span><span class="hl-brackets">)</span></pre></div></div>
<p>Well it&#8217;s not really magic! All that the parse.py file does is import the string module. When a Parse instance is created, a string representation of the string module that was imported is printed out to the command line.</p>
<p>In other words, what happens here is:</p>
<ol>
<li>my_proj.py imports the tokenizer package, which then imports Parse from parse.py.</li>
<li>my_project.py then creates an instance of the Parse object.</li>
<li>The Parse instance will then print out a string representation of the string module it imported.</li>
</ol>
<p>When we run my_proj.py, we get the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-brackets">&lt;</span><span class="hl-reserved">module</span><span class="hl-code"> '</span><span class="hl-var">tokenizer</span><span class="hl-code">.</span><span class="hl-var">string</span><span class="hl-code">' </span><span class="hl-var">from</span><span class="hl-code"> '/</span><span class="hl-reserved">home</span><span class="hl-code">/</span><span class="hl-reserved">project</span><span class="hl-code">/</span><span class="hl-reserved">tokenizer</span><span class="hl-code">/</span><span class="hl-reserved">string</span><span class="hl-code">.</span><span class="hl-var">py</span><span class="hl-code">'</span><span class="hl-brackets">&gt;
&lt;/</span><span class="hl-reserved">module</span><span class="hl-brackets">&gt;</span></pre></div></div>
<p>As we can see, our local string module was imported by the parse.py module. This is a relative import which means that the &#8220;import statement first looks in the containing package before looking in the standard module search path.&#8221; <a href="http://docs.python.org/tut/node8.html#SECTION008420000000000000000">[7]</a></p>
<h2>So What&#8217;s the Problem?</h2>
<p>I&#8217;m sure that many of you realize that there is a string module built into Python, and that our string module and the built-in string module share the same name. As long as everything in the tokenizer package only needs the tokenizer.string module, and not the built-in string module, everything will be fine.</p>
<p>But what happens a few months down the road when some new module in the tokenizer package needs to import the built-in string module? Whenever it tries to import string it gets tokenizer.string instead.  The obvious solution is to make sure that your module does not share the same name as a built-in module. But this does not fully solve the problem, as we can&#8217;t anticipate the names of future modules that will be added to the standard distribution.</p>
<h2>Absolute Imports</h2>
<p>PEP 328 describes the issue explained in our tokenizer example and the solution that the Python team has put in place:</p>
<p>&#8220;In Python 2.4 and earlier, if you&#8217;re reading a module located inside a package, it is not clear whether import foo refers to a top-level module or to another module inside the package. As Python&#8217;s library expands, more and more existing package internal modules suddenly shadow standard library modules by accident. It&#8217;s a particularly difficult problem inside packages because there&#8217;s no way to specify which module is meant. To resolve the ambiguity, it is proposed that foo will always be a module or package reachable from sys.path. This is called an absolute<br />
import.&#8221; <a href="http://www.python.org/dev/peps/pep-0328/#rationale-for-absolute-imports">[8]</a></p>
<p>As stated earlier, once Python gets to version 3.0 all import statements will be absolute imports. We can already use this functionality in Python 2.5 by using a future statement to import absolute_import from the __future__ module:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">__future__ </span><span class="hl-reserved">import </span><span class="hl-identifier">absolute_import</span></pre></div></div>
<p>When we add a future statement to parse.py that imports the absolute_import feature, it will look like the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">__future__ </span><span class="hl-reserved">import </span><span class="hl-identifier">absolute_import
</span><span class="hl-reserved">import </span><span class="hl-identifier">string

</span><span class="hl-reserved">class </span><span class="hl-identifier">Parse</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">print</span><span class="hl-brackets">(</span><span class="hl-identifier">string</span><span class="hl-brackets">)</span></pre></div></div>
<p>When we run my_proj.py, the output will be something similar to the following:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-brackets">&lt;</span><span class="hl-reserved">module</span><span class="hl-code"> '</span><span class="hl-var">string</span><span class="hl-code">' </span><span class="hl-var">from</span><span class="hl-code"> '/</span><span class="hl-reserved">usr</span><span class="hl-code">/</span><span class="hl-reserved">lib</span><span class="hl-code">/</span><span class="hl-reserved">python2</span><span class="hl-code">.</span><span class="hl-var">5</span><span class="hl-code">/</span><span class="hl-reserved">string</span><span class="hl-code">.</span><span class="hl-var">pyc</span><span class="hl-code">'</span><span class="hl-brackets">&gt;&lt;/</span><span class="hl-reserved">module</span><span class="hl-brackets">&gt;</span></pre></div></div>
<p>As you can see, enabling absolute imports changes import string from a relative import into an absolute import.  This solves our problem when we want import string to import the built-in module, but what about when we want to import the local string module in the tokenizer package? The solution is to use an absolute import to import the local module. The following version of parse.py will import the local string module:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">__future__ </span><span class="hl-reserved">import </span><span class="hl-identifier">absolute_import
</span><span class="hl-reserved">from </span><span class="hl-identifier">tokenizer </span><span class="hl-reserved">import </span><span class="hl-identifier">string

</span><span class="hl-reserved">class </span><span class="hl-identifier">Parse</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">print</span><span class="hl-brackets">(</span><span class="hl-identifier">string</span><span class="hl-brackets">)</span></pre></div></div>
<p>We can also use the following absolute import to import the local string module:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">__future__ </span><span class="hl-reserved">import </span><span class="hl-identifier">absolute_import
</span><span class="hl-reserved">import </span><span class="hl-identifier">tokenizer</span><span class="hl-default">.</span><span class="hl-identifier">string

</span><span class="hl-reserved">class </span><span class="hl-identifier">Parse</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">print</span><span class="hl-brackets">(</span><span class="hl-identifier">tokenizer</span><span class="hl-code">.</span><span class="hl-identifier">string</span><span class="hl-brackets">)</span></pre></div></div>
<h2>Relative Imports in an Absolute World</h2>
<p>Once you start importing the absolute_import feature, you may still want to use relative imports. Relative imports generally are not needed in smaller packages. But if you have a very large package that contains many sub-packages, you might not want to rewrite your import statements every time the internal structure of the main package changes. Fortunately, it is still possible to perform relative imports in Python 3.0 or with absolute_imports enabled.  If you want to perform a relative import, you will need to use the following syntax:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">from</span><span class="hl-default"> . </span><span class="hl-reserved">import </span><span class="hl-identifier">foo</span></pre></div></div>
<p>Notice that a dot is used to indicate that the import is a relative import.  &#8220;A single leading dot indicates a relative import, starting with the current package. Two or more leading dots give a relative import to the parent(s) of the current package, one level per dot after the first.&#8221;<a href="http://www.python.org/dev/peps/pep-0328/#guido-s-decision">[9]</a> The &#8220;dot syntax&#8221; is only available to imports that use the &#8220;from&#8221; syntax. &#8220;import . foo&#8221; is not allowed.</p>
<p>To import our local string module in the parse.py module with absolute imports turned on, we do the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">__future__ </span><span class="hl-reserved">import </span><span class="hl-identifier">absolute_import
</span><span class="hl-reserved">from</span><span class="hl-default"> . </span><span class="hl-reserved">import </span><span class="hl-identifier">string

</span><span class="hl-reserved">class </span><span class="hl-identifier">Parse</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">print</span><span class="hl-brackets">(</span><span class="hl-identifier">string</span><span class="hl-brackets">)</span></pre></div></div>
<h2>Conclusion</h2>
<p>I hope I have convinced you that importing division and absolute_imports from the __future__ module is an easy way to add a little &#8220;3.0 protection&#8221; to your current Python projects. Deciding to make these changes as you create new code, will make migrating your code to Python 3.0 an easier process when the big day comes.</p>
<p>Of course these are not the only changes that you should start making to your code to prepare for Python 3.0.  (For example, some of you may have noticed that I was using the print function in this article and not the print statement. Since the print statement is no longer going to be available in Python 3.0, I&#8217;m trying to get used to using the print function.) If you want a more detailed description of all the upcoming changes to Python 3.0, and steps you can take to prepare your code now, please see the Python wiki. <a href="http://wiki.python.org/moin/FutureProofPython">[10]</a></p>
<p>You don&#8217;t have to worry about Python 3.0 too much right now since the true migration path will be through Python 2.6 and the tools that will be made available. In fact for some people full migration to Python 3.0 may be many years away. But like Guido said it&#8217;s best to be prepared and start writing future-proof code now. <a href="http://www.python.org/doc/essays/ppt/pycon2008/Py3kAndYou.pdf">[11]</a></p>
<p>[1] <a href="http://www.python.org/dev/peps/pep-0361/">http://www.python.org/dev/peps/pep-0361/</a><br />
[2] <a href="http://www.python.org/doc/essays/ppt/pycon2008/Py3kAndYou.pdf">http://www.python.org/doc/essays/ppt/pycon2008/Py3kAndYou.pdf</a><br />
[3] <a href="http://www.python.org/doc/essays/ppt/pycon2008/Py3kAndYou.pdf">http://www.python.org/doc/essays/ppt/pycon2008/Py3kAndYou.pdf</a><br />
[4] <a href="http://www.python.org/doc/essays/ppt/pycon2008/Py3kAndYou.pdf">http://www.python.org/doc/essays/ppt/pycon2008/Py3kAndYou.pdf</a><br />
[5] <a href="http://docs.python.org/ref/future.html">http://docs.python.org/ref/future.html</a><br />
[6] <a href="http://www.python.org/dev/peps/pep-0328/#rationale-for-absolute-imports">http://www.python.org/dev/peps/pep-0328/#rationale-for-absolute-imports</a><br />
[7] <a href="http://docs.python.org/tut/node8.html#SECTION008420000000000000000">http://docs.python.org/tut/node8.html#SECTION008420000000000000000</a><br />
[8] <a href="http://www.python.org/dev/peps/pep-0328/#rationale-for-absolute-imports">http://www.python.org/dev/peps/pep-0328/#rationale-for-absolute-imports</a><br />
[9] <a href="http://www.python.org/dev/peps/pep-0328/#guido-s-decision">http://www.python.org/dev/peps/pep-0328/#guido-s-decision</a><br />
[10] <a href="http://wiki.python.org/moin/FutureProofPython">http://wiki.python.org/moin/FutureProofPython</a><br />
[11] <a href="http://www.python.org/doc/essays/ppt/pycon2008/Py3kAndYou.pdf">http://www.python.org/doc/essays/ppt/pycon2008/Py3kAndYou.pdf</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2010/09/22/using-future-statements-to-prepare-for-the-future/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Python Version Poll Results</title>
		<link>http://www.learningpython.com/2010/08/13/python-version-pol-results/</link>
		<comments>http://www.learningpython.com/2010/08/13/python-version-pol-results/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 04:20:15 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=202</guid>
		<description><![CDATA[The results are in for the first annual LearningPython.com Python version quiz: By a landslide version 2.6 is the winner, with 3.1 and 2.5 following far behind. A grand total of 1084 people voted and 700 of those still use Python 2.6, 187 use 3.1 and 182 use 2.5. While not the largest sampling of [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F08%2F13%2Fpython-version-pol-results%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F08%2F13%2Fpython-version-pol-results%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>The results are in for the first annual LearningPython.com Python version quiz:</p>
Note: There is a poll embedded within this post, please visit the site to participate in this post's poll.
<p>By a landslide version 2.6 is the winner, with 3.1 and 2.5 following far behind. A grand total of 1084 people voted and 700 of those still use Python 2.6, 187 use 3.1 and 182 use 2.5. While not the largest sampling of users the wide margin of victory probably means that most Python programmers are still targeting 2.6, or at the very least the newest version of the 2.x branch.  Now what is installed on our end user&#8217;s system&#8230;that&#8217;s another matter all together.</p>
<p>Thanks again to everyone that voted. I&#8217;m happy that I was able to attract 1000+ people to vote in this poll. My next idea for a poll is an IDE poll, partially because I&#8217;m curious as to what people are using, and partially because there is a good chance that I may have overlooked other programs on my way to selecting <a href="http://www.geany.org/">Geany</a>.</p>
<p><strong>Note</strong>: Python 2.7 was released (July 3rd, 2010) after the poll was created (Mach 4, 2010) this means that the value for 2.7 is probably larger now and 2.6 is probably slightly smaller.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2010/08/13/python-version-pol-results/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Introducing Descriptors and Properties</title>
		<link>http://www.learningpython.com/2010/04/25/introducing-descriptors-and-properties/</link>
		<comments>http://www.learningpython.com/2010/04/25/introducing-descriptors-and-properties/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 01:21:51 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[Python Magazine]]></category>
		<category><![CDATA[descriptors]]></category>
		<category><![CDATA[properties]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=186</guid>
		<description><![CDATA[Note: This article was first published the May 2008 issue of Python Magazine Introducing Descriptors and Properties Mark Mruss New-style classes were introduced to Python with the release of Python 2.2. And with these new-style classes came descriptors and properties. This article will introduce the descriptor protocol, descriptors, and properties. Introduction New-style classes were introduced [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F04%2F25%2Fintroducing-descriptors-and-properties%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F04%2F25%2Fintroducing-descriptors-and-properties%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Note: This article was first published the <a href="http://www.pythonmagazine.com/c/issue/view/69">May 2008</a> issue of <a href="http://www.pythonmagazine.com/">Python Magazine</a></p>
<p><strong>Introducing Descriptors and Properties</strong></p>
<p><strong>Mark Mruss</strong></p>
<p>New-style classes were introduced to Python with the release of Python 2.2. And with these new-style classes came descriptors and properties. This article will introduce the descriptor protocol, descriptors, and properties.</p>
<h2>Introduction</h2>
<p>New-style classes were introduced to Python with the release of Python 2.2.  A new-style class is any class that is derived from the <code>object</code> base class. New-style classes give Python programmers many new (and initially confusing) features. One such feature is the descriptor protocol, and more specifically descriptors themselves.</p>
<p>Descriptors give Python programmers the ability to easily and efficiently create &#8220;managed attributes&#8221;. Managed attributes can be thought of as attributes that are not accessed directly. Instead their access is &#8220;managed&#8221; by something else, generally a class or a function.</p>
<p>If you haven&#8217;t come across this before you are probably wondering why one would want to manage attribute access? One reason might be that you don&#8217;t want people to be able to delete the attribute. Another reason may be that you need to ensure that your attribute data is always valid. Or perhaps attribute <code>x</code> is based on attribute <code>y</code>, so every time the value of <code>y</code> changes you want to update the value of <code>x</code>.  From these few examples you can see the many possible cases where you might want to control access to certain attributes.</p>
<p>For those of you familiar with other programming languages, this type of access is often referred to as &#8220;getters and setters&#8221;.  In many language, implementing &#8220;getters and setters&#8221; means using private variables and public functions that get and set the variable&#8217;s value. Since Python doesn&#8217;t (really) have private variables, the descriptor protocol is basically a built-in and Python-ic way to way to achieve something similar.</p>
<p>This article will introduce you to the descriptor protocol, descriptors, and properties. It will focus on demonstrating how to use them to create managed attributes. Since the descriptor protocol requires new-style classes, all of the examples in this article require Python 2.2 or newer.</p>
<p><span id="more-186"></span></p>
<h2>A few definitions</h2>
<p>Before moving forward, it is important to understand a few related terms. These terms will introduce some basic concepts and help you follow along with the remainder of the article.</p>
<p><strong>descriptor protocol</strong> &#8211; The following three methods make up the descriptor protocol: <code>__get__</code>, <code>__set__</code>, and <code>__delete__</code>.</p>
<p><strong>descriptor</strong> &#8211; An &#8220;object attribute with <code>binding behavior</code>, one whose attribute access has been overridden by methods in the descriptor protocol.&#8221; <a href="http://docs.python.org/ref/descriptor-invocation.html">[1]</a> In other words an &#8220;attributes whose usage resembles attribute access, but whose implementation uses method calls.&#8221;<a href="http://www.python.org/download/releases/2.2/descrintro/#property">[2]</a></p>
<p><strong>data descriptor</strong> &#8211; A descriptor with the <code>__get__</code> and <code>__set__</code> methods of the descriptor protocol defined.</p>
<p><strong>non-data descriptor</strong> &#8211; A descriptor with only the <code>__get__</code>  method of the descriptor protocol defined. &#8220;Python methods (including staticmethod() and classmethod()) are implemented as non-data descriptors.&#8221; <a href="http://docs.python.org/ref/descriptor-invocation.html">[3]</a></p>
<p><strong>property</strong> &#8211; A built-in type that implements the descriptor protocol and allows you to easily create data descriptors.</p>
<p>Don&#8217;t worry if you don&#8217;t fully understand these definitions, the remainder of this article will hopefully clarify any confusion you have.</p>
<h2>The Descriptor Protocol</h2>
<p>Let&#8217;s take a closer look at the descriptor protocol and see how we can use it to create a descriptor.  As previously mentioned, the descriptor protocol is made up of three methods: <code>__get__</code>, <code>__set__</code>, and <code>__delete__</code>.  These methods have specific signatures and they are as follows, where <code>self</code> is the class that owns the methods:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">__get__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">instance</span><span class="hl-code">, </span><span class="hl-identifier">owner</span><span class="hl-brackets">)
</span><span class="hl-identifier">__set__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">instance</span><span class="hl-code">, </span><span class="hl-identifier">value</span><span class="hl-brackets">)
</span><span class="hl-identifier">__delete__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">instance</span><span class="hl-brackets">)</span></pre></div></div>
<p>These three methods represent the three basic operations that you perform on attributes in general: querying the value of that attribute; assigning a value to it; and, (very rarely) deleting it. They work as follows:</p>
<ul>
<li>
The <code>__get__</code> method is called when the attributes value is being queried.  The <code>__get__</code> method should return the (computed) attribute value or raise an AttributeError exception.&#8221; <a href="http://docs.python.org/ref/descriptors.html">[4]</a> This is where access to the attribute&#8217;s value is managed.
</li>
<li>
The <code>__set__</code> method is used in the assignment operation. It is called when we want to set the attribute value. This is where you can control what values, or types of values are being assigned to your attribute.
</li>
<li>Finally, the <code>__delete__</code> method is called when we want to delete the attribute. Here you can (rarely) decide whether or not to delete the attribute.
</li>
</ul>
<p>There are also three different parameters passed to the three methods (excluding the standard <code>self</code> parameter for methods that belong to a class):</p>
<ul>
<li>
<code>owner</code> &#8211; This &#8220;is always the owner class.&#8221; <a href="http://docs.python.org/ref/descriptors.html">[5]</a> This means that it is the actual class, and not an instance of the class. So if the descriptor is in a class called <code>MyClass</code>, <code>owner</code> will be that class.
</li>
<li>
<code>instance</code> &#8211; An instance of class type <code>owner</code>. It is &#8220;the instance that the attribute was accessed through&#8221; <a href="http://docs.python.org/ref/descriptors.html">[6]</a>, or <code>None</code> if the attribute is being accessed through the class (<code>owner</code>) instead of an instance.
</li>
<li>
<code>value</code>- The value that the attribute is being set to.
</li>
</ul>
<p>This difference between <code>owner</code> and <code>instance</code> might be a bit confusing, so let&#8217;s look at a quick example. LetÃ¢Â€Â™s say we have a descriptor <code>my_descriptor</code> in the class <code>MyClass</code>, if we were to run the following code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">my_class_instance</span><span class="hl-default"> = </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">()
</span><span class="hl-reserved">print </span><span class="hl-identifier">my_class_instance</span><span class="hl-default">.</span><span class="hl-identifier">my_descriptor</span></pre></div></div>
<p>The second line queries the descriptors value and results in the <code>__get__</code> method being called with the <code>instance</code> parameter being <code>my_class_instance</code>. The <code>owner</code> parameter will be the <code>MyClass</code> class.</p>
<p><strong>Note:</strong> Notice that we treat the descriptor <code>my_descriptor</code> as though it is a normal attribute. We don&#8217;t call <code>print my_class_instance.my_descriptor.__get__(my_class, MyClass)</code>. This is what was meant by: &#8220;attributes whose usage resembles attribute access, but whose implementation uses method calls.&#8221;<a href="http://www.python.org/download/releases/2.2/descrintro/#property">[7]</a></p>
<p>If the following code were run:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">print </span><span class="hl-identifier">MyClass</span><span class="hl-default">.</span><span class="hl-identifier">my_descriptor</span></pre></div></div>
<p>The <code>__get__</code> method will again be called. This time the <code>instance</code> parameter will be <code>None</code> and the <code>owner</code> parameter will be the <code>MyClass</code> class.</p>
<p><strong>Note:</strong> Only the <code>__get__</code> method has the <code>owner</code> parameter. This means that it is the only function in the descriptor protocol that can be accessed through the class. Setting and deleting the descriptor through the class actually changes <strong>what</strong> the variable is. For example, if we tried to assign the numeric value 2 to a descriptor variable using the class, we would not access the descriptors <code>__set__</code> method. Instead we would change the type of the variable from a descriptor to an integer with the value of 2.</p>
<h2>A Simple Descriptor Example</h2>
<p>A simple &#8220;transparent&#8221; descriptor example can be found in Listing 1. The first thing to notice in the code is that both the <code>SimpleDescriptor</code> and <code>MyClass</code> classes are &#8220;new-style&#8221; classes because they are derived from <code>object</code>. This is important because, as mentioned above, descriptors only work with &#8220;new-style&#8221; classes. The second point to notice is that the descriptor has class scope as opposed to instance scope. There are also two extra print statements included in the code. They are there to let us follow the execution a little more easily.</p>
<p><strong>Listing 1</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">SimpleDescriptor</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

    </span><span class="hl-reserved">def </span><span class="hl-identifier">__get__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">instance</span><span class="hl-code">, </span><span class="hl-identifier">owner</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-comment"># Check if the value has been set
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-reserved">not </span><span class="hl-builtin">hasattr</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">_value</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">))</span><span class="hl-default">:
            </span><span class="hl-reserved">raise AttributeError
        print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Getting value: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">_value
        </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">_value

    </span><span class="hl-reserved">def </span><span class="hl-identifier">__set__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">instance</span><span class="hl-code">, </span><span class="hl-identifier">value</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Setting to %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">value
        self</span><span class="hl-default">.</span><span class="hl-identifier">_value</span><span class="hl-default"> = </span><span class="hl-identifier">value

    </span><span class="hl-reserved">def </span><span class="hl-identifier">__delete__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">instance</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">del</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_value</span><span class="hl-brackets">)

</span><span class="hl-reserved">class </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-identifier">SimpleDescriptor</span><span class="hl-brackets">()</span></pre></div></div>
<p>Using Listing 1 to execute the following code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">my_instance</span><span class="hl-default"> = </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">()
</span><span class="hl-identifier">my_instance</span><span class="hl-default">.</span><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-number">416
</span><span class="hl-reserved">print </span><span class="hl-identifier">my_instance</span><span class="hl-default">.</span><span class="hl-identifier">my_value</span></pre></div></div>
<p>The output would be the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">Setting to </span><span class="hl-number">416
</span><span class="hl-identifier">Getting value</span><span class="hl-default">: </span><span class="hl-number">416
416</span></pre></div></div>
<p>As you can see the second line (<code>my_instance.data_descriptor = 416</code>) calls the <code>__set__</code> method and sets the _value attribute. When we call <code>print my_instance.data_descriptor</code> the <code>__get__</code>, method is called and the <code>_value</code> attribute is returned.</p>
<h2>The Problem with the Simple Example</h2>
<p>The previous example may look like a perfectly good descriptor, but there is something wrong with it. Take a look at what happens when we runs this new code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">my_instance</span><span class="hl-default"> = </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">() </span><span class="hl-comment">#Create the first instance
</span><span class="hl-identifier">my_instance</span><span class="hl-default">.</span><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-number">416 </span><span class="hl-comment">#Set its' value
</span><span class="hl-identifier">my_second_instance</span><span class="hl-default"> = </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">() </span><span class="hl-comment">#Create the second instance
</span><span class="hl-identifier">my_second_instance</span><span class="hl-default">.</span><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-number">204 </span><span class="hl-comment">#Set its' value
</span><span class="hl-reserved">print </span><span class="hl-identifier">my_instance</span><span class="hl-default">.</span><span class="hl-identifier">my_value </span><span class="hl-comment">#What was the fist instance's value?</span></pre></div></div>
<p>We get the following output:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">Setting to </span><span class="hl-number">416
</span><span class="hl-identifier">Setting to </span><span class="hl-number">204
</span><span class="hl-identifier">Getting value</span><span class="hl-default">: </span><span class="hl-number">204
204</span></pre></div></div>
<p>Notice that when we set the second instance&#8217;s <code>my_value</code> descriptor to be 204, we are also setting the first instances. This is because <code>my_value</code> has class scope, so both instances (and the class itself) share the same instance of the <code>SimpleDescriptor</code> class. Since <code>SimpleDescriptor</code> only stores one value, they all actually share the same value. We will get the same results if we check what the classes value of <code>my_value</code> is:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">my_instance</span><span class="hl-default"> = </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">() </span><span class="hl-comment">#Create the first instance
</span><span class="hl-identifier">my_instance</span><span class="hl-default">.</span><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-number">416 </span><span class="hl-comment">#Set its' value
</span><span class="hl-identifier">my_second_instance</span><span class="hl-default"> = </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">() </span><span class="hl-comment">#Create the second instance
</span><span class="hl-identifier">my_second_instance</span><span class="hl-default">.</span><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-number">204 </span><span class="hl-comment">#Set its' value
</span><span class="hl-reserved">print </span><span class="hl-identifier">MyClass</span><span class="hl-default">.</span><span class="hl-identifier">my_value </span><span class="hl-comment">#What's the classes value?</span></pre></div></div>
<p>We get the following results:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">Setting to </span><span class="hl-number">416
</span><span class="hl-identifier">Setting to </span><span class="hl-number">204
</span><span class="hl-identifier">Getting value</span><span class="hl-default">: </span><span class="hl-number">204
204</span></pre></div></div>
<p>In the last line of the code (<code>print MyClass.my_value #What's the classes value?</code>) we simply use the class (ignoring both instances) in order to get the value of <code>my_data</code>. This will be an instance where the <code>__get__</code> function will be called with the <code>instance</code> parameter set to <code>None</code>.</p>
<p><strong>Note:</strong> This is not a problem if you want to share the value across all instances.</p>
<h2>The Solution to the Problem</h2>
<p>In order to get around this issue, you have to remember that if you want values unique to each instance your descriptors must store values that are unique to each instance. This can be in the instance itself, in dictionary in the descriptor, or perhaps in a text file. Just make sure that the value is unique to each instance. Though it seems like a simple solution, in practice a suitable solution for all cases is difficult to implement. As a result you should probably pick a specific implementation for your specific situations.</p>
<p>Using each instance as a key, one can store the value in a dictionary in the descriptor itself. The problem with this solution should be obvious to programmers familiar with Python dictionaries: only immutable types can be used as keys. This is fine if you know what object you are working with, but what about in the future when you want to add a descriptor to your sub-classed list?</p>
<p>Another solution is to store the value in the instance itself. You can do this by easily adding the value to the instance&#8217;s <code>__dict__</code>. The limitation is that the descriptor need to be given a suitable key so that there is no collision with anything already in the instance&#8217;s <code>__dict__</code>.</p>
<p>Listing 2 shows a solution to the problem from the previous section where the value is stored in the instance&#8217;s <code>__dict__</code>. Values are indexed using a key name provided during the creation of the descriptor.  Aside from where we store the value, there is little difference between Listing 1 and Listing 2.  Notice that the value name is a converted into a string. This is done to ensure that it can be used as a key.</p>
<p><strong>Listing 2</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">FixedDescriptor</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">value_name</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">value_name</span><span class="hl-default"> = </span><span class="hl-builtin">str</span><span class="hl-brackets">(</span><span class="hl-identifier">value_name</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">__get__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">instance</span><span class="hl-code">, </span><span class="hl-identifier">owner</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">instance </span><span class="hl-reserved">is None</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">raise AttributeError
    </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-reserved">not </span><span class="hl-identifier">instance</span><span class="hl-code">.</span><span class="hl-identifier">__dict__</span><span class="hl-code">.</span><span class="hl-identifier">has_key</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">value_name</span><span class="hl-brackets">))</span><span class="hl-default">:
        </span><span class="hl-reserved">raise AttributeError
    return </span><span class="hl-identifier">instance</span><span class="hl-default">.</span><span class="hl-identifier">__dict__</span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">value_name</span><span class="hl-brackets">]

    </span><span class="hl-reserved">def </span><span class="hl-identifier">__set__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">instance</span><span class="hl-code">, </span><span class="hl-identifier">value</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Setting to %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">value
        instance</span><span class="hl-default">.</span><span class="hl-identifier">__dict__</span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">value_name</span><span class="hl-brackets">]</span><span class="hl-default"> = </span><span class="hl-identifier">value

    </span><span class="hl-reserved">def </span><span class="hl-identifier">__delete__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">instance</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">instance</span><span class="hl-code">.</span><span class="hl-identifier">__dict__</span><span class="hl-code">.</span><span class="hl-identifier">has_key</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">value_name</span><span class="hl-brackets">))</span><span class="hl-default">:
            </span><span class="hl-identifier">del</span><span class="hl-brackets">(</span><span class="hl-identifier">instance</span><span class="hl-code">.</span><span class="hl-identifier">__dict__</span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">value_name</span><span class="hl-brackets">])


</span><span class="hl-reserved">class </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-identifier">FixedDescriptor</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">__value</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>The major usage difference between Listing 1 and Listing 2 is the fact that the <code>__get__</code> method no longer works at class level; it only works at instance level. This should be obvious since this solution stores the value in the instance.  If there is no instance, we have nowhere to store the value!  If you attempt to access the descriptor at class level (the first if statement) an attribute error will be raised:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">__get__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">instance</span><span class="hl-code">, </span><span class="hl-identifier">owner</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">instance </span><span class="hl-reserved">is None</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">raise AttributeError
    </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-reserved">not </span><span class="hl-identifier">instance</span><span class="hl-code">.</span><span class="hl-identifier">__dict__</span><span class="hl-code">.</span><span class="hl-identifier">has_key</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">value_name</span><span class="hl-brackets">))</span><span class="hl-default">:
        </span><span class="hl-reserved">raise AttributeError
    return </span><span class="hl-identifier">instance</span><span class="hl-default">.</span><span class="hl-identifier">__dict__</span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">value_name</span><span class="hl-brackets">]</span></pre></div></div>
<h2>Easy Data Descriptors with Properties</h2>
<p>The descriptor provided in Listing 2 will work for many situations but for my money the easiest way to implement data descriptors is to use the <code>property</code> type. I would recommend using it unless you need the same descriptor across many different classes or attributes (i.e. for type validation). Properties can be thought of as a simple and easy way to create data descriptors. The <code>property</code> type implements the descriptor protocol and gets around the problem of where to store the descriptor value in an easy way: it lets the class that created the descriptor deal with it.</p>
<p>The full signature of the <code>property</code> function is as follows:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">fget</span><span class="hl-code">=</span><span class="hl-reserved">None</span><span class="hl-code">, </span><span class="hl-identifier">fset</span><span class="hl-code">=</span><span class="hl-reserved">None</span><span class="hl-code">, </span><span class="hl-identifier">fdel</span><span class="hl-code">=</span><span class="hl-reserved">None</span><span class="hl-code">, </span><span class="hl-identifier">doc</span><span class="hl-code">=</span><span class="hl-reserved">None</span><span class="hl-brackets">)</span></pre></div></div>
<p>Where <code>fget</code>, <code>fset</code>, <code>fdel</code> are methods that will be called when the <code>__get__</code>, <code>__set__</code>, and <code>__del__</code> members of the descriptor protocol are called. The <code>doc</code> parameter is a string that will be used as the docstring for the descriptor.  If the <code>doc</code> parameter is not specified, the docstring of the <code>fget</code> method is used.</p>
<p>The signature of the <code>fget</code>, <code>fset</code>, <code>fdel</code> functions are as follows:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">fget</span><span class="hl-brackets">(</span><span class="hl-identifier">instance</span><span class="hl-brackets">)
</span><span class="hl-identifier">fset</span><span class="hl-brackets">(</span><span class="hl-identifier">instance</span><span class="hl-code">, </span><span class="hl-identifier">value</span><span class="hl-brackets">)
</span><span class="hl-identifier">fdel</span><span class="hl-brackets">(</span><span class="hl-identifier">instance</span><span class="hl-brackets">)</span></pre></div></div>
<p>In the three signatures, <code>instance</code> is a reference to the object that owns the property attribute. This is the same instance that gets passed to the descriptor protocol.  Since <code>instance</code> is the first parameter of each method, these are, for all intents and purposes, member methods of a class. The <code>value</code> parameter is the same as the <code>value</code> parameter that is passed to the <code>__set__</code> method. It is what we are setting the attribute to.</p>
<p>The basic way to implement properties can be seen in Listing 3. As you can see, what we do for a property is very similar to what we did for our initial descriptor in Listing 1. We set up the three functions necessary for the descriptor protocol, and then use them to create our property attribute.  Creating the property is very simple:</p>
<p><strong>Listing 3</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-comment">#Create the fget, fset, and fdel methods
    </span><span class="hl-reserved">def </span><span class="hl-identifier">__get_value</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Getting value: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__value
        </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__value

    </span><span class="hl-reserved">def </span><span class="hl-identifier">__set_value</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">value</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Setting to %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">value
        self</span><span class="hl-default">.</span><span class="hl-identifier">__value</span><span class="hl-default"> = </span><span class="hl-identifier">value

    </span><span class="hl-reserved">def </span><span class="hl-identifier">__del_value</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">del</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">__value</span><span class="hl-brackets">)

    </span><span class="hl-comment">#Create the property
    </span><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_value</span><span class="hl-code">
            , </span><span class="hl-identifier">__set_value</span><span class="hl-code">
            , </span><span class="hl-identifier">__del_value</span><span class="hl-code">
            , </span><span class="hl-quotes">&quot;</span><span class="hl-string">This is my property</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">value</span><span class="hl-code">=</span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-identifier">value</span></pre></div></div>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_value</span><span class="hl-code">
        , </span><span class="hl-identifier">__set_value</span><span class="hl-code">
        , </span><span class="hl-identifier">__del_value</span><span class="hl-code">
        , </span><span class="hl-quotes">&quot;</span><span class="hl-string">This is my property</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<h2>Make Data Attributes Data-Descriptors</h2>
<p>A common reason to use descriptors is to create read-only attributes. This means allowing callers to get (or access) an attribute&#8217;s value, but not allowing them to set its&#8217; value. At first glance it seems as though one can accomplish this by using descriptors with only the <code>__get__</code> method defined, i.e. a &#8220;non-data descriptor&#8221;.</p>
<p>While this seems to create a read-only descriptor attribute, it actually does nothing of the sort. Instead of using the descriptor&#8217;s <code>__set__</code> function for the assignment operation (since no <code>__set__</code> function is defined), the default Python assignment operation is used. This means that instead of stopping the assignment operation, a new attribute will be created in the instance (remember that descriptors have class scope) having the same name as the descriptor attribute and taking precedence in future operations.</p>
<p>This may be a bit confusing so let&#8217;s look at the example in Listing 4. It&#8217;s very much like our previous descriptor examples except it does not specify the <code>__set__</code> and <code>__del__</code> functions. LetÃ¢Â€Â™s look at what happens when we try to use this as though it were a read-only attribute:</p>
<p><strong>Listing 4</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">WonkyDescriptor</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This Descriptor isn't read only</span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">value_name</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">value_name</span><span class="hl-default"> = </span><span class="hl-builtin">str</span><span class="hl-brackets">(</span><span class="hl-identifier">value_name</span><span class="hl-brackets">)

    </span><span class="hl-reserved">def </span><span class="hl-identifier">__get__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">instance</span><span class="hl-code">, </span><span class="hl-identifier">owner</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">instance </span><span class="hl-reserved">is None</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-reserved">raise AttributeError
        </span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-reserved">not </span><span class="hl-identifier">instance</span><span class="hl-code">.</span><span class="hl-identifier">__dict__</span><span class="hl-code">.</span><span class="hl-identifier">has_key</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">value_name</span><span class="hl-brackets">))</span><span class="hl-default">:
            </span><span class="hl-reserved">raise AttributeError
        print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Getting a value</span><span class="hl-quotes">&quot;
        </span><span class="hl-reserved">return </span><span class="hl-identifier">instance</span><span class="hl-default">.</span><span class="hl-identifier">__dict__</span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">value_name</span><span class="hl-brackets">]

</span><span class="hl-reserved">class </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

    </span><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-identifier">WonkyDescriptor</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">_value</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

    </span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">value</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-comment">#initial value
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">_value</span><span class="hl-default"> = </span><span class="hl-identifier">value</span></pre></div></div>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">my_instance</span><span class="hl-default"> = </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">(</span><span class="hl-number">23</span><span class="hl-brackets">) </span><span class="hl-comment">#Create the first instance
</span><span class="hl-reserved">print </span><span class="hl-identifier">my_instance</span><span class="hl-default">.</span><span class="hl-identifier">my_value
my_instance</span><span class="hl-default">.</span><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Don't set me!</span><span class="hl-quotes">&quot;
</span><span class="hl-reserved">print </span><span class="hl-identifier">my_instance</span><span class="hl-default">.</span><span class="hl-identifier">my_value</span></pre></div></div>
<p>When we run this, we get the following output:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">Getting a value
</span><span class="hl-number">23
</span><span class="hl-identifier">Don</span><span class="hl-quotes">'</span><span class="hl-string">t set me!</span></pre></div></div>
<p>As you can see we did not succeed in creating a read-only attribute, instead something else happened. The &#8220;Getting a value&#8221; string is printed out when we print out <code>my_value</code> for the first time. This means that we are accessing the value through the descriptor. We then set the value of the descriptor attribute and print out that new value. Since &#8220;Getting a value&#8221; isn&#8217;t printed out a second time, we know that the descriptor&#8217;s <code>__get__</code> method is not accessed when the second print statement is called.</p>
<p>Let&#8217;s take a closer look at what is happening using the following code, which prints out the instance&#8217;s <code>__dict__</code>:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">my_instance</span><span class="hl-default"> = </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">(</span><span class="hl-number">23</span><span class="hl-brackets">) </span><span class="hl-comment">#Create the first instance
</span><span class="hl-reserved">print </span><span class="hl-identifier">my_instance</span><span class="hl-default">.</span><span class="hl-identifier">__dict__
my_instance</span><span class="hl-default">.</span><span class="hl-identifier">my_value</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Don't set me!</span><span class="hl-quotes">&quot;
</span><span class="hl-reserved">print </span><span class="hl-identifier">my_instance</span><span class="hl-default">.</span><span class="hl-identifier">__dict__</span></pre></div></div>
<p>This results in the following, which explains what is happening:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">{</span><span class="hl-quotes">'</span><span class="hl-string">_value</span><span class="hl-quotes">'</span><span class="hl-default">: </span><span class="hl-number">23</span><span class="hl-default">}
{</span><span class="hl-quotes">'</span><span class="hl-string">_value</span><span class="hl-quotes">'</span><span class="hl-default">: </span><span class="hl-number">23</span><span class="hl-default">, </span><span class="hl-quotes">'</span><span class="hl-string">my_value</span><span class="hl-quotes">'</span><span class="hl-default">: </span><span class="hl-quotes">&quot;</span><span class="hl-string">Don't set me!</span><span class="hl-quotes">&quot;</span><span class="hl-default">}</span></pre></div></div>
<p>When we first access the <code>__dict__</code> we see our value indexed by the <code>_value</code> key that we told the descriptor to use. Now look at the second <code>__dict__</code>. The old value is still there, but so is a new value <code>my_value</code>. When we assigned &#8220;Don&#8217;t set me!&#8221; to <code>my_value</code>, we didn&#8217;t overwrite the descriptor attribute at class scope, we created a new instance attribute! And it is not exactly a read-only attribute.</p>
<p>In order to create a read-only attribute, you need to create a <code>data descriptor</code> where the <code>__set__</code> method raises an <code>AttributeError</code> exception. An easy way to do this is to create a <code>property</code> and only set the <code>fget</code> function. Instead of using the descriptor in Listing 4, we can construct a read-only attribute as follows:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">__get_value</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">_value
my_value</span><span class="hl-default"> = </span><span class="hl-builtin">property</span><span class="hl-brackets">(</span><span class="hl-identifier">__get_value</span><span class="hl-brackets">)</span></pre></div></div>
<h2>Conclusion</h2>
<p>I hope that after reading this article you can see how powerful descriptors (especially data-descriptors) can be. Once you get the hang of them, they are a great way to implement &#8220;getters and setters&#8221; and read-only attributes. Data-Descriptors are also very useful for performing validation during the assignment operation, i.e. ensuring that a value remains a specific type, or in a specific form.</p>
<p>The more you play with descriptors and use them in your code, the more you&#8217;ll see how sophisticated and useful they can be. That being said, it&#8217;s important to remember that unless you have a good reason to use descriptors you probably don&#8217;t need them. There&#8217;s no need to sacrifice the readability of your code or the dynamism of Python just for the sake of using descriptors. But when you have a real reason for managed attributes, you&#8217;ll find that descriptors are more than up to the task.</p>
<p>[1] <a href="http://docs.python.org/ref/descriptor-invocation.html">http://docs.python.org/ref/descriptor-invocation.html</a><br />
[2] <a href="http://www.python.org/download/releases/2.2/descrintro/#property">http://www.python.org/download/releases/2.2/descrintro/#property</a><br />
[3] <a href="http://docs.python.org/ref/descriptor-invocation.html">http://docs.python.org/ref/descriptor-invocation.html</a><br />
[4] <a href="http://docs.python.org/ref/descriptors.html">http://docs.python.org/ref/descriptors.html</a><br />
[5] <a href="http://docs.python.org/ref/descriptors.html">http://docs.python.org/ref/descriptors.html</a><br />
[6] <a href="http://docs.python.org/ref/descriptors.html">http://docs.python.org/ref/descriptors.html</a><br />
[7] <a href="http://www.python.org/download/releases/2.2/descrintro/#property">http://www.python.org/download/releases/2.2/descrintro/#property</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2010/04/25/introducing-descriptors-and-properties/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Forums Forums Forums</title>
		<link>http://www.learningpython.com/2010/04/08/forums-forums-forums-2/</link>
		<comments>http://www.learningpython.com/2010/04/08/forums-forums-forums-2/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 03:05:33 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[forums]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=183</guid>
		<description><![CDATA[I just wanted to re-point out the fact that there are some forums associated with this blog. There&#8217;s not much happening there, and recently they have become a haven for spammers, but I&#8217;m trying to clean them up and if other Python programmers read this blog maybe the forums could actually become useful! Either way [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F04%2F08%2Fforums-forums-forums-2%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F04%2F08%2Fforums-forums-forums-2%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I just wanted to re-point out the fact that there are some <a href="http://www.learningpython.com/forums">forums associated with this blog</a>.  There&#8217;s not much happening there, and recently they have become a haven for spammers, but I&#8217;m trying to clean them up and if other Python programmers read this blog maybe the forums could actually become useful!</p>
<p>Either way for those that didn&#8217;t know, there are <a href="http://www.learningpython.com/forums">learning python forums</a> available.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2010/04/08/forums-forums-forums-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Poll: Python Version</title>
		<link>http://www.learningpython.com/2010/03/04/poll-python-version/</link>
		<comments>http://www.learningpython.com/2010/03/04/poll-python-version/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 03:52:10 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[Poll]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=154</guid>
		<description><![CDATA[Edit: Due to popular demand (well a couple of comments) I&#8217;ve decided to allow multiple answers to the poll. This should make everyone that uses two versions happy. With two major versions of Python available to us Python programmers (2.X and 3.X) I thought it would be interesting to see which version the readers of [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F03%2F04%2Fpoll-python-version%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F03%2F04%2Fpoll-python-version%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>Edit:</strong> Due to popular demand (well a couple of comments) I&#8217;ve decided to allow multiple answers to the poll. This should make everyone that uses two versions happy.</p>
<p>With two major versions of Python available to us Python programmers (<a href="http://docs.python.org/">2.X</a> and <a href="http://docs.python.org/3.1/index.html">3.X</a>) I thought it would be interesting to see which version the readers of this blog are using and targeting. </p>
<p>Personally I&#8217;m still using 2.5 on my Debian box because it&#8217;s the default, and 2.6 on my Windows PC.  While I have used 3.X and have it installed, I&#8217;ve remained on the 2.X branch largely because many of the modules that I play around with are still focused on the 2.X branch so that&#8217;s where my focus has remained. </p>
<p>I voted 2.5 since I do that majority of my programing on my Debian box. So now what about you: Note: There is a poll embedded within this post, please visit the site to participate in this post's poll.</p>
<p>If you want to explain your choice leave a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2010/03/04/poll-python-version/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>An Introduction to Google Calendars</title>
		<link>http://www.learningpython.com/2010/02/27/an-introduction-to-google-calendars/</link>
		<comments>http://www.learningpython.com/2010/02/27/an-introduction-to-google-calendars/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 05:14:18 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[Python Magazine]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=135</guid>
		<description><![CDATA[Note: This article was first published the March 2008 issue of Python Magazine Mark Mruss Over the past few years Google has expanded it&#8217;s services beyond those of a normal search engine. One of those new services is the Google Calendar. This article will provide an introduction to working with the Google Calendar using Python. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F02%2F27%2Fan-introduction-to-google-calendars%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F02%2F27%2Fan-introduction-to-google-calendars%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Note: This article was first published the <a href="http://www.pythonmagazine.com/c/issue/view/67">March 2008</a> issue of <a href="http://www.pythonmagazine.com/">Python Magazine</a></p>
<p><strong>Mark Mruss</strong></p>
<p>Over the past few years Google has expanded it&#8217;s services beyond those of a normal search engine. One of those new services is the Google Calendar. This article will provide an introduction to working with the Google Calendar using Python.</p>
<h2>Introduction</h2>
<p>As many of you know, Google has branched out and started offering more services besides their ubiquitous search engine. You have email, calendars, documents, spreadsheets, photos, maps, videos, source code hosting, and the list goes on. Fortunately for us Python programmers, Google released the Google data Python Client Library on March 26th, 2007, giving Python programmers easy access to some of these services.</p>
<p><span id="more-135"></span></p>
<p>What the Google data Python Client Library, or &#8220;gdata-python-client&#8221;, does is provide &#8220;a library and source code that makes it easy to access data through Google Data APIs.&#8221; <a href="http://code.google.com/p/gdata-python-client/">[1]</a> This leads to the question: &#8220;what are the Google Data APIs?&#8221; In the words of Google: &#8220;The Google data APIs provide a simple standard protocol for reading and writing data on the web. These APIs use either of two standard XML-based syndication formats: Atom or RSS.&#8221;<a href="http://code.google.com/apis/gdata/index.html">[2]</a></p>
<p>The Google services that use the Google data APIs include many of the services that we have grown to know and love:</p>
<ul>
<li>Google Apps</li>
<li>Google Base</li>
<li>Blogger</li>
<li>Google Calendar</li>
<li>Google Code Search</li>
<li>Google Documents</li>
<li>Google Notebook</li>
<li>Picasa Web Albums</li>
<li>Spreadsheets</li>
<li>YouTube</li>
</ul>
<p>This tutorial will only deal with the Google Calendar service specifically, but it&#8217;s important to know that many of the techniques used here can easily be applied to other Google services.</p>
<p>The Google data Python Client Library requires Python 2.2 or greater and the ElementTree module to be installed. I recommend using Python 2.5 since the ElementTree module is included in that release of Python. This column assumes that you are using Python 2.5 and version 1.0.10 of the &#8220;gdata-python-client&#8221;.</p>
<h2>Getting and Installing  the &#8220;gdata-python-client&#8221;</h2>
<p>We must first download and install the &#8220;gdata-python-client&#8221; files from the &#8220;gdata-python-client&#8221; website.<a href="http://code.google.com/p/gdata-python-client/">[3]</a> Once you have downloaded the compressed file, extract it&#8217;s contents to a folder. You will then need to browse to that folder and run the extracted <code>setup.py</code> file with the <code>install</code> command with root access. For me, the command looked like this:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-comment"># python2.5 setup.py install</span></pre></div></div>
<p>Notice that I ran <code>python2.5</code> instead of simply <code>python</code>. I did this to ensure that Python 2.5 was used instead of a previous version of Python.</p>
<p>Once you have done this, you can test to make sure that the <code>gdata-python-client</code> module has been installed properly by trying to import the <code>gdata</code> module. You can test this easily in the interactive Python shell:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">$ </span><span class="hl-identifier">python2</span><span class="hl-number">.5
</span><span class="hl-identifier">Python </span><span class="hl-number">2.5.2</span><span class="hl-identifier">a0 </span><span class="hl-brackets">(</span><span class="hl-identifier">r251</span><span class="hl-code">:</span><span class="hl-number">54863</span><span class="hl-code">, </span><span class="hl-identifier">Jan  </span><span class="hl-number">3 2008</span><span class="hl-code">, </span><span class="hl-number">17</span><span class="hl-code">:</span><span class="hl-number">59</span><span class="hl-code">:</span><span class="hl-number">56</span><span class="hl-brackets">)
[</span><span class="hl-identifier">GCC </span><span class="hl-number">4.2.3 20071123 </span><span class="hl-brackets">(</span><span class="hl-identifier">prerelease</span><span class="hl-brackets">) (</span><span class="hl-identifier">Debian </span><span class="hl-number">4.2.2</span><span class="hl-code">-</span><span class="hl-number">4</span><span class="hl-brackets">)] </span><span class="hl-identifier">on linux2
Type </span><span class="hl-quotes">&quot;</span><span class="hl-string">help</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">copyright</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">credits</span><span class="hl-quotes">&quot; </span><span class="hl-reserved">or </span><span class="hl-quotes">&quot;</span><span class="hl-string">license</span><span class="hl-quotes">&quot; </span><span class="hl-reserved">for </span><span class="hl-identifier">more information</span><span class="hl-default">.
&gt;&gt;&gt; </span><span class="hl-reserved">import </span><span class="hl-identifier">gdata</span><span class="hl-default">
&gt;&gt;&gt;</span></pre></div></div>
<p>If everything works properly you should see no errors when importing <code>gdata</code>. If you do run into problems, you can consult the <code>install.txt</code> file that was extracted with the rest of the files in the &#8220;gdata-python-client&#8221; archive that you downloaded.</p>
<h2>Getting Started</h2>
<p>There are some great Google Calendar examples that come with the &#8220;gdata-python-client&#8221; module. I found them to be very useful learning tools. The &#8220;Google Calendar Developers Guide&#8221;<a href="http://code.google.com/apis/calendar/developers_guide_python.html">[4]</a> is also very helpful. If you get stuck it is essential reading. The &#8220;Google Calendar API Reference Guide&#8221;<a href="http://code.google.com/apis/calendar/reference.html">[5]</a> is also an indispensable help.</p>
<p>It is important to remember that when you are working with the Google Calendar service, you are actually working with XML data. You are sending and receiving XML data to and from the Google Calendar service &#8211; Atom or RSS feeds to be precise. The Python classes that wrap these feeds, or XML blocks, are dynamically &#8220;formed&#8221; around the XML. When you access something like the following:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">e_link</span><span class="hl-default">.</span><span class="hl-identifier">href</span></pre></div></div>
<p>You are actually accessing the &#8220;href&#8221; attribute of an XML link block that may look something like this:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-brackets">&lt;</span><span class="hl-reserved">ns0 </span><span class="hl-var">:link href</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">http://www.google.com/calendar/feeds/&lt;username&gt;/private/full</span><span class="hl-quotes">&quot; </span><span class="hl-var">rel</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">alternate</span><span class="hl-quotes">&quot; </span><span class="hl-var">type</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">application/atom+xml</span><span class="hl-quotes">&quot; </span><span class="hl-var">xmlns:ns0</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">http:www.w3.org/2005/Atom</span><span class="hl-quotes">&quot; </span><span class="hl-brackets">/&gt;</span></pre></div></div>
<p>In the above example, if we had the link as an instance (perhaps an <code>atom.Link</code> object), <code>e_link.rel</code> would be equal to &#8220;alternate&#8221;.</p>
<h2>Logging In</h2>
<p>There are two types of Google calendars &#8211; public calendars and private calendars. Public calendars do not require any authentication while private calendars do. There are three forms of authentication for private calendars: &#8220;AuthSub proxy&#8221; authentication, &#8220;ClientLogin&#8221; authentication, and &#8220;Magic cookie&#8221; authentication.</p>
<p>&#8220;AuthSub proxy&#8221; authentication is meant for web applications so it will not be covered in this tutorial. &#8220;Magic cookie&#8221; authentication requires a string (the magic cookie) obtained from your Google Calendar settings page. This type of authentication gives you read only access to a private calendar. Its usage is quite specific and will not be covered in this column either.</p>
<p>For this column we will focus on good old-fashioned &#8220;ClientLogin&#8221; authentication. In order to perform &#8220;ClientLogin&#8221; authentication we need two things: a Google Calendar username and a password. If you do not have these, head over to the Google Calendar website <a href="http://www.google.com/calendar">[6]</a> and get yourself signed up. If you have gmail or have signed up for other Google services, you can probably sign in using that username and password.</p>
<p><strong>Note:</strong> I say username and so does the documentation, but this will actually be an email address.</p>
<p>We are going to read the username and password in from the command line using the <code>raw_input</code> function and the <code>getpass</code> module. I must thank the people who wrote the Google code examples for introducing me to the <code>getpass</code> module. Before looking through the examples, I had not heard of it.</p>
<p>The <code>raw_input</code> function simply reads a line of input from the command line and returns it with the newline stripped.  The <code>getpass.getpass</code> function does the exact same thing as <code>raw_input</code> except it does not echo the input, which is handy when working with passwords.</p>
<p>We need to import the <code>getpass</code> module:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">getpass</span></pre></div></div>
<p>Then, in our <code>main</code> function we will ask the user to input their username and password:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:
    </span><span class="hl-identifier">username</span><span class="hl-default"> = </span><span class="hl-builtin">raw_input</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Enter your username: </span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">password</span><span class="hl-default"> = </span><span class="hl-identifier">getpass</span><span class="hl-default">.</span><span class="hl-identifier">getpass</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Enter your password: </span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
    </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>Now that we have our username and password, we need to log the user in. To do this we are going to use the <code>CalendarService</code> class. The <code>CalendarService</code> &#8220;extends the GDataService to streamline Google Calendar operations.&#8221; <a href="#7">[7]</a> The <code>GDataService</code> class &#8220;provides CRUD ops. and programmatic login for GData services.&#8221; <a href="#8">[8]</a>. CRUD is an acronym that stands for Create, Retrieve, Update, and Delete. What the <code>CalendarService</code> class will allow us to do is create, retrieve, update, and delete things from a Google Calendar.</p>
<p>The first step in logging in is to create an instance of the <code>CalendarService</code> class. To do this we will pass in the username and password that we have collected:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">calendar_service</span><span class="hl-default"> = </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">calendar</span><span class="hl-default">.</span><span class="hl-identifier">service</span><span class="hl-default">.</span><span class="hl-identifier">CalendarService</span><span class="hl-brackets">(</span><span class="hl-identifier">username</span><span class="hl-code">
    , </span><span class="hl-identifier">password</span><span class="hl-code">
    , </span><span class="hl-quotes">&quot;</span><span class="hl-string">PythonMagazine-Calendar_Example-1.0</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>The third parameter that we pass to the <code>CalendarService</code> constructor is the &#8220;source&#8221; string. This is a short &#8220;string identifying your application, for logging purposes. This string should take the form: &#8220;companyName-applicationName-versionID&#8221;"<a href="http://code.google.com/apis/accounts/AuthForInstalledApps.html">[9]</a></p>
<p>Now that we have a <code>CalendarService</code> instance, we need to login. To do this we will use the <code>ProgrammaticLogin</code> function. This will log into the Google Calendar using the <code>CalendarService</code> classes current username and password.  The <code>ProgrammaticLogin</code> function can raise three possible exceptions that we want to be aware of:</p>
<ol>
<li><strong>CaptchaRequired</strong> &#8211; Raised if the login requires a &#8220;captcha&#8221; response in order to login.</li>
<li><strong>BadAuthentication</strong> &#8211; Raised if the username and/or password were not accepted by the Google Calendar.</li>
<li><strong>Error</strong> &#8211; Raised if a 403 error occurs that is not a &#8220;CaptchaRequired&#8221; or &#8220;BadAuthentication&#8221; error.</li>
</ol>
<p>For this example, shown in Listing 1, we will only worry about the &#8220;BadAuthentication&#8221; exception.</p>
<p><strong>Listing 1</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:
    </span><span class="hl-identifier">username</span><span class="hl-default"> = </span><span class="hl-builtin">raw_input</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Enter your username: </span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">password</span><span class="hl-default"> = </span><span class="hl-identifier">getpass</span><span class="hl-default">.</span><span class="hl-identifier">getpass</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Enter your password: </span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

    </span><span class="hl-identifier">calendar_service</span><span class="hl-default"> = </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">calendar</span><span class="hl-default">.</span><span class="hl-identifier">service</span><span class="hl-default">.</span><span class="hl-identifier">CalendarService</span><span class="hl-brackets">(</span><span class="hl-identifier">username</span><span class="hl-code">
        , </span><span class="hl-identifier">password</span><span class="hl-code">
        , </span><span class="hl-quotes">&quot;</span><span class="hl-string">PythonMagazine-Calendar_Example-1.0</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-reserved">try</span><span class="hl-default">:
        </span><span class="hl-identifier">calendar_service</span><span class="hl-default">.</span><span class="hl-identifier">ProgrammaticLogin</span><span class="hl-brackets">()
    </span><span class="hl-reserved">except </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">service</span><span class="hl-default">.</span><span class="hl-identifier">BadAuthentication</span><span class="hl-default">, </span><span class="hl-identifier">e</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Authentication error logging in: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">e
        </span><span class="hl-reserved">return
    except Exception</span><span class="hl-default">, </span><span class="hl-identifier">e</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Error Logging in: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">e
        </span><span class="hl-reserved">return</span></pre></div></div>
<h2>Working With Calendars</h2>
<p>Now that we&#8217;ve logged into the calendar service, we can start working with the user&#8217;s available calendars. To get a list of all of the available calendars you can call the <code>GetAllCalendarsFeed</code> function. This will return a <code>CalendarListFeed</code> instance representing all of the userÃ¢Â€Â™s calendars. Since I want to show how to add and delete Calendars, I&#8217;m going to use the <code>GetOwnCalendarsFeed</code> function to get a list of all of the calendars that the &#8220;authenticated user has owner access to.&#8221;<a href="http://code.google.com/apis/calendar/developers_guide_python.html">[10]</a></p>
<p>The <code>GetOwnCalendarsFeed</code> function returns a <code>CalendarListFeed</code> class instance. This contains some information (like a title) along with a list of <code>CalendarListEntry</code> classes. Each <code>CalendarListEntry</code> in this list represents a calendar. An example of a function that uses <code>GetOwnCalendarsFeed</code> and then prints out information about each calendar can be found in Listing 2. Sample output from this function can be found in Listing 3. The function was passed a <code>CalendarService</code> after logging in:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">list_own_calendars</span><span class="hl-brackets">(</span><span class="hl-identifier">calendar_service</span><span class="hl-brackets">)</span></pre></div></div>
<p><strong>Listing 2</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">list_own_calendars</span><span class="hl-brackets">(</span><span class="hl-identifier">calendar_service</span><span class="hl-brackets">)</span><span class="hl-default">:

    </span><span class="hl-reserved">try</span><span class="hl-default">:
        </span><span class="hl-comment">#Get the CalendarListFeed
        </span><span class="hl-identifier">all_calendars_feed</span><span class="hl-default"> = </span><span class="hl-identifier">calendar_service</span><span class="hl-default">.</span><span class="hl-identifier">GetOwnCalendarsFeed</span><span class="hl-brackets">()
    </span><span class="hl-reserved">except Exception</span><span class="hl-default">, </span><span class="hl-identifier">e</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Error getting all calendar feed: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">e</span><span class="hl-brackets">)
        </span><span class="hl-reserved">return
    </span><span class="hl-comment">#Print the feed's title
    </span><span class="hl-reserved">print </span><span class="hl-identifier">all_calendars_feed</span><span class="hl-default">.</span><span class="hl-identifier">title</span><span class="hl-default">.</span><span class="hl-identifier">text
    </span><span class="hl-comment">#Now loop through all of the CalendarListEntry items.
    </span><span class="hl-identifier">for </span><span class="hl-brackets">(</span><span class="hl-identifier">index</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-brackets">) </span><span class="hl-reserved">in </span><span class="hl-builtin">enumerate</span><span class="hl-brackets">(</span><span class="hl-identifier">all_calendars_feed</span><span class="hl-code">.</span><span class="hl-identifier">entry</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-comment">#Print out the title and the summary if ther is one
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">summary </span><span class="hl-reserved">is not None</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">%d) %s - Summary: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(
                </span><span class="hl-identifier">index</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">title</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">summary</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-brackets">)
        </span><span class="hl-reserved">else</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">%d) %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">index</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">title</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-brackets">)
        </span><span class="hl-comment">#Print out the authors
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t</span><span class="hl-string">Authors:</span><span class="hl-quotes">&quot;
        </span><span class="hl-reserved">for </span><span class="hl-identifier">author </span><span class="hl-reserved">in </span><span class="hl-identifier">cal</span><span class="hl-default">.</span><span class="hl-identifier">author</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t\t</span><span class="hl-string">%s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">author</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-brackets">)
        </span><span class="hl-comment">#Print out other information
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t</span><span class="hl-string">Published: %s </span><span class="hl-special">\n\t</span><span class="hl-string">Updated: %s </span><span class="hl-special">\n\t</span><span class="hl-string">timezone: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(
            </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">published</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">updated</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">timezone</span><span class="hl-code">.</span><span class="hl-identifier">value</span><span class="hl-brackets">)
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t</span><span class="hl-string">Colour: %s </span><span class="hl-special">\n\t</span><span class="hl-string">Hidden: %s </span><span class="hl-special">\n\t</span><span class="hl-string">Selected: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(
            </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">color</span><span class="hl-code">.</span><span class="hl-identifier">value</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">hidden</span><span class="hl-code">.</span><span class="hl-identifier">value</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">selected</span><span class="hl-code">.</span><span class="hl-identifier">value</span><span class="hl-brackets">)
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t</span><span class="hl-string">Access Level: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">access_level</span><span class="hl-code">.</span><span class="hl-identifier">value</span><span class="hl-brackets">)</span></pre></div></div>
<p><strong>Listing 3</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre>Mark Mruss's Calendar List
0) Mark Mruss - Summary: Main Calendar
	Authors:
		Mark Mruss
	Published: 2008-02-07T04:15:15.701Z
	Updated: 2008-02-07T03:43:26.000Z
	timezone: America/Toronto
	Colour: #5229A3
	Hidden: false
	Selected: true
	Access Level: owner
1) PythonMagazine - Summary: Calendar for Articles
	Authors:
		PythonMagazine
	Published: 2008-02-07T04:15:15.702Z
	Updated: 2008-02-07T03:37:15.000Z
	timezone: America/Toronto
	Colour: #0D7813
	Hidden: false
	Selected: true
	Access Level: owner</pre></div></div>
<h2>Adding a Calendar</h2>
<p>If we want to add a calendar, we need to create a <code>CalendarListEntry</code> class instance and then call the <code>CalendarService</code> classes <code>InsertCalendar</code> function. Let&#8217;s say I wanted to add a Banking calendar to my account, I could do the following to create the <code>CalendarListEntry</code>:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">new_calendar</span><span class="hl-default"> = </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">calendar</span><span class="hl-default">.</span><span class="hl-identifier">CalendarListEntry</span><span class="hl-brackets">()
</span><span class="hl-identifier">new_calendar</span><span class="hl-default">.</span><span class="hl-identifier">title</span><span class="hl-default"> = </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">atom</span><span class="hl-default">.</span><span class="hl-identifier">Title</span><span class="hl-brackets">(</span><span class="hl-identifier">text</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">Banking</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">new_calendar</span><span class="hl-default">.</span><span class="hl-identifier">summary</span><span class="hl-default"> = </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">atom</span><span class="hl-default">.</span><span class="hl-identifier">Summary</span><span class="hl-brackets">(</span><span class="hl-identifier">text</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">Bills and payments</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">new_calendar</span><span class="hl-default">.</span><span class="hl-identifier">timezone</span><span class="hl-default"> = </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">calendar</span><span class="hl-default">.</span><span class="hl-identifier">Timezone</span><span class="hl-brackets">(</span><span class="hl-identifier">value</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">America/Toronto</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">new_calendar</span><span class="hl-default">.</span><span class="hl-identifier">hidden</span><span class="hl-default"> = </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">calendar</span><span class="hl-default">.</span><span class="hl-identifier">Hidden</span><span class="hl-brackets">(</span><span class="hl-identifier">value</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">false</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">new_calendar</span><span class="hl-default">.</span><span class="hl-identifier">selected</span><span class="hl-default"> = </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">calendar</span><span class="hl-default">.</span><span class="hl-identifier">Selected</span><span class="hl-brackets">(</span><span class="hl-identifier">value</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">true</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>The calendar now needs to be added to the account:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">try</span><span class="hl-default">:
    </span><span class="hl-identifier">created_calendar</span><span class="hl-default"> = </span><span class="hl-identifier">calendar_service</span><span class="hl-default">.</span><span class="hl-identifier">InsertCalendar</span><span class="hl-brackets">(</span><span class="hl-identifier">new_calendar</span><span class="hl-brackets">)
</span><span class="hl-reserved">except </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">service</span><span class="hl-default">.</span><span class="hl-identifier">RequestError</span><span class="hl-default">, </span><span class="hl-identifier">e</span><span class="hl-default">:
    </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Error adding calendar: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">e</span><span class="hl-brackets">[</span><span class="hl-number">0</span><span class="hl-brackets">][</span><span class="hl-quotes">&quot;</span><span class="hl-string">reason</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">])</span></pre></div></div>
<p>This will add the new calendar to the authenticated users list of calendars, make it visible, and select it. Notice that <code>InsertCalendar</code> also returns a <code>CalendarListEntry</code> instance. This is the calendar that was actually added to the authenticated userÃ¢Â€Â™s list of calendars. It is wrapping the XML that represents the actual calendar, as opposed to the smaller version that we created for insertion.</p>
<h2>Deleting a Calendar</h2>
<p>Deleting a Calendar is very easy. You simply need to call the <code>CalendarService</code> classes <code>DeleteCalendarEntry</code> function. The <code>DeleteCalendarEntry</code> function takes three parameters which are documented in the source code:</p>
<ol>
<li><strong>edit_uri</strong> &#8211; The edit uri (Uniform Resource Identifier) of the Calendar that you want to delete.</li>
<li><strong>url_params</strong> &#8211; Defaults to None. A dictionary containing URL parameters that will be included in the delete.</li>
<li><strong>escape_params</strong> &#8211; Defaults to True. A boolean that controls whether or not the <code>url_params</code> will be escaped.</li>
</ol>
<p><strong>Note</strong>: There is another optional parameter: <code>extra_headers</code>, which is the second parameter, but at this point it does not seem to be used at all in the source code.</p>
<p>The simplest case is to ignore the optional parameters and simply pass in the edit uri of the calendar that you wish to delete. You can get the edit uri of a calendar by calling the <code>GetEditLink</code> function of the <code>CalendarListEntry</code> instance that represents the calendar that you are going to delete. An example of a function that will delete a calendar can be seen in Listing 4. This function takes a <code>CalendarService</code> instance and a <code>CalendarListEntry</code> instance as parameters.</p>
<p><strong>Listing 4</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">delete_calendar</span><span class="hl-brackets">(</span><span class="hl-identifier">calendar_service</span><span class="hl-code">, </span><span class="hl-identifier">calendar</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">e_link</span><span class="hl-default"> = </span><span class="hl-identifier">calendar</span><span class="hl-default">.</span><span class="hl-identifier">GetEditLink</span><span class="hl-brackets">()
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">e_link </span><span class="hl-reserved">is not None</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">try</span><span class="hl-default">:
            </span><span class="hl-identifier">calendar_service</span><span class="hl-default">.</span><span class="hl-identifier">DeleteCalendarEntry</span><span class="hl-brackets">(</span><span class="hl-identifier">e_link</span><span class="hl-code">.</span><span class="hl-identifier">href</span><span class="hl-brackets">)
        </span><span class="hl-reserved">except </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">service</span><span class="hl-default">.</span><span class="hl-identifier">RequestError</span><span class="hl-default">, </span><span class="hl-identifier">e</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Error deleting calendar: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">e</span><span class="hl-brackets">[</span><span class="hl-number">0</span><span class="hl-brackets">][</span><span class="hl-quotes">&quot;</span><span class="hl-string">reason</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">])</span></pre></div></div>
<h2>Listing Events</h2>
<p>Now letÃ¢Â€Â™s take a look at events. Events are items that are added to a specific calendar. If you want to remind yourself to pay your bills at the end of the month you might add that to your banking calendar. That &#8220;note&#8221; on your calendar is an event.</p>
<p>You can get a list of events for the primary calendar using the <code>CalendarService</code> classes <code>GetCalendarEventFeed</code> function. Since you may be working with more than one calendar, it&#8217;s probably more useful to be able to list the events for a specific calendar. You can do this in one of two ways:</p>
<ol>
<li>You can pass in the optional <code>uri</code> parameter to the <code>GetCalendarEventFeed</code> function.  From testing I found that a Calendar&#8217;s &#8220;alternate&#8221; link works.</li>
<li>You can use the  <code>CalendarService</code> classes <code>CalendarQuery</code> function to query for a specific calendars event feed.</li>
</ol>
<p>If you want to use the first option you can use the <code>CalendarListEntry</code> classes <code>GetAlternateLink</code> member function to get the uri, and then pass it to <code>GetCalendarEventFeed</code>:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">a_link</span><span class="hl-default"> = </span><span class="hl-identifier">calendar</span><span class="hl-default">.</span><span class="hl-identifier">GetAlternateLink</span><span class="hl-brackets">()
</span><span class="hl-comment">#Make sure the link is valid
</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">a_link </span><span class="hl-reserved">is not None</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">event_feed</span><span class="hl-default"> = </span><span class="hl-identifier">calendar_service</span><span class="hl-default">.</span><span class="hl-identifier">GetCalendarEventFeed</span><span class="hl-brackets">(</span><span class="hl-identifier">a_link</span><span class="hl-code">.</span><span class="hl-identifier">href</span><span class="hl-brackets">)</span></pre></div></div>
<p>If you use the <code>CalendarQuery</code> method, you need to get the calendar username (or id) of the calendar whose events you want to query. It seems strange to me that there appears to be no way to get a calendar&#8217;s username besides parsing one of the calendar&#8217;s links. The username of a calendar can be found in the alternate link after &#8220;feeds&#8221; and before the visibility and projection:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-default">http://www.google.com/calendar/feeds/</span><span class="hl-brackets">&lt;</span><span class="hl-code"> &lt;</span><span class="hl-reserved">username</span><span class="hl-brackets">&gt;</span><span class="hl-default">&gt;/private/full</span></pre></div></div>
<p>Note: You can use the username &#8220;default&#8221; to query the default calendar.</p>
<p>For the sake of simplicity I will use the alternate link method for my examples. A full example that prints out calendar data and a calendar&#8217;s events can be found in Listing 5. The method that prints out the event data is called <code>print_event_feed</code>. It is called near the end of the <code>list_own_calendars</code> method:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment"># Now Print out the events
</span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Events:</span><span class="hl-quotes">&quot;
</span><span class="hl-identifier">a_link</span><span class="hl-default"> = </span><span class="hl-identifier">cal</span><span class="hl-default">.</span><span class="hl-identifier">GetAlternateLink</span><span class="hl-brackets">()
</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">a_link </span><span class="hl-reserved">is not None</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">event_feed</span><span class="hl-default"> = </span><span class="hl-identifier">calendar_service</span><span class="hl-default">.</span><span class="hl-identifier">GetCalendarEventFeed</span><span class="hl-brackets">(</span><span class="hl-identifier">a_link</span><span class="hl-code">.</span><span class="hl-identifier">href</span><span class="hl-brackets">)
    </span><span class="hl-identifier">print_event_feed</span><span class="hl-brackets">(</span><span class="hl-identifier">event_feed</span><span class="hl-brackets">)</span></pre></div></div>
<p><strong>Listing 5</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#! /usr/bin/env python

</span><span class="hl-reserved">import </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">calendar</span><span class="hl-default">.</span><span class="hl-identifier">service
</span><span class="hl-reserved">import </span><span class="hl-identifier">getpass

</span><span class="hl-reserved">def </span><span class="hl-identifier">print_event_feed</span><span class="hl-brackets">(</span><span class="hl-identifier">event_feed</span><span class="hl-brackets">)</span><span class="hl-default">:

    </span><span class="hl-reserved">for </span><span class="hl-identifier">index</span><span class="hl-default">, </span><span class="hl-identifier">event </span><span class="hl-reserved">in </span><span class="hl-builtin">enumerate</span><span class="hl-brackets">(</span><span class="hl-identifier">event_feed</span><span class="hl-code">.</span><span class="hl-identifier">entry</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t</span><span class="hl-string">%d) %s</span><span class="hl-special">\r\n\t</span><span class="hl-string">Content: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(
                </span><span class="hl-identifier">index</span><span class="hl-code">, </span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">title</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-code">, </span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">content</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-brackets">)
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t\t</span><span class="hl-string">Who:</span><span class="hl-quotes">&quot;
        </span><span class="hl-reserved">for </span><span class="hl-identifier">person </span><span class="hl-reserved">in </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">who</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t\t\t</span><span class="hl-string">Name: %s</span><span class="hl-special">\n\t\t\t</span><span class="hl-string">email: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">person</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-code">
                , </span><span class="hl-identifier">person</span><span class="hl-code">.</span><span class="hl-identifier">email</span><span class="hl-brackets">)
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t\t</span><span class="hl-string">Authors:</span><span class="hl-quotes">&quot;
        </span><span class="hl-reserved">for </span><span class="hl-identifier">author </span><span class="hl-reserved">in </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">author</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t\t\t</span><span class="hl-string">%s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">author</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-brackets">)
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t\t</span><span class="hl-string">When:</span><span class="hl-quotes">&quot;
        </span><span class="hl-reserved">for </span><span class="hl-identifier">e_index</span><span class="hl-default">, </span><span class="hl-identifier">e_time </span><span class="hl-reserved">in </span><span class="hl-builtin">enumerate</span><span class="hl-brackets">(</span><span class="hl-identifier">event</span><span class="hl-code">.</span><span class="hl-identifier">when</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t\t\t</span><span class="hl-string">%d) Start time: %s</span><span class="hl-special">\n\t\t\t</span><span class="hl-string">End time: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(
                </span><span class="hl-identifier">e_index</span><span class="hl-code">
                , </span><span class="hl-identifier">e_time</span><span class="hl-code">.</span><span class="hl-identifier">start_time</span><span class="hl-code">
                , </span><span class="hl-identifier">e_time</span><span class="hl-code">.</span><span class="hl-identifier">end_time</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">list_own_calendars</span><span class="hl-brackets">(</span><span class="hl-identifier">calendar_service</span><span class="hl-brackets">)</span><span class="hl-default">:

    </span><span class="hl-reserved">try</span><span class="hl-default">:
        </span><span class="hl-comment">#Get the CalendarListFeed
        </span><span class="hl-identifier">all_calendars_feed</span><span class="hl-default"> = </span><span class="hl-identifier">calendar_service</span><span class="hl-default">.</span><span class="hl-identifier">GetOwnCalendarsFeed</span><span class="hl-brackets">()
    </span><span class="hl-reserved">except Exception</span><span class="hl-default">, </span><span class="hl-identifier">e</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Error getting all calendar feed: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">e</span><span class="hl-brackets">)
        </span><span class="hl-reserved">return
    </span><span class="hl-comment">#Print the feed's title
    </span><span class="hl-reserved">print </span><span class="hl-identifier">all_calendars_feed</span><span class="hl-default">.</span><span class="hl-identifier">title</span><span class="hl-default">.</span><span class="hl-identifier">text
    </span><span class="hl-comment">#Now loop through all of the CalendarListEntry items.
    </span><span class="hl-identifier">for </span><span class="hl-brackets">(</span><span class="hl-identifier">index</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-brackets">) </span><span class="hl-reserved">in </span><span class="hl-builtin">enumerate</span><span class="hl-brackets">(</span><span class="hl-identifier">all_calendars_feed</span><span class="hl-code">.</span><span class="hl-identifier">entry</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-comment">#Print out the title and the summary if there is one
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">summary </span><span class="hl-reserved">is not None</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">%d) %s - Summary: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(
                </span><span class="hl-identifier">index</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">title</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">summary</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-brackets">)
        </span><span class="hl-reserved">else</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">%d) %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">index</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">title</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-brackets">)
        </span><span class="hl-comment">#Print out the authors
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t</span><span class="hl-string">Authors:</span><span class="hl-quotes">&quot;
        </span><span class="hl-reserved">for </span><span class="hl-identifier">author </span><span class="hl-reserved">in </span><span class="hl-identifier">cal</span><span class="hl-default">.</span><span class="hl-identifier">author</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t\t</span><span class="hl-string">%s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">author</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-brackets">)
        </span><span class="hl-comment">#Print out other information
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t</span><span class="hl-string">Published: %s </span><span class="hl-special">\n\t</span><span class="hl-string">Updated: %s </span><span class="hl-special">\n\t</span><span class="hl-string">timezone: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(
            </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">published</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">updated</span><span class="hl-code">.</span><span class="hl-identifier">text</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">timezone</span><span class="hl-code">.</span><span class="hl-identifier">value</span><span class="hl-brackets">)
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t</span><span class="hl-string">Colour: %s </span><span class="hl-special">\n\t</span><span class="hl-string">Hidden: %s </span><span class="hl-special">\n\t</span><span class="hl-string">Selected: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(
            </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">color</span><span class="hl-code">.</span><span class="hl-identifier">value</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">hidden</span><span class="hl-code">.</span><span class="hl-identifier">value</span><span class="hl-code">, </span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">selected</span><span class="hl-code">.</span><span class="hl-identifier">value</span><span class="hl-brackets">)
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t</span><span class="hl-string">Access Level: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">cal</span><span class="hl-code">.</span><span class="hl-identifier">access_level</span><span class="hl-code">.</span><span class="hl-identifier">value</span><span class="hl-brackets">)
        </span><span class="hl-comment"># Now Print out the events
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-special">\t</span><span class="hl-string">Events:</span><span class="hl-quotes">&quot;
        </span><span class="hl-identifier">a_link</span><span class="hl-default"> = </span><span class="hl-identifier">cal</span><span class="hl-default">.</span><span class="hl-identifier">GetAlternateLink</span><span class="hl-brackets">()
        </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">a_link </span><span class="hl-reserved">is not None</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-identifier">event_feed</span><span class="hl-default"> = </span><span class="hl-identifier">calendar_service</span><span class="hl-default">.</span><span class="hl-identifier">GetCalendarEventFeed</span><span class="hl-brackets">(</span><span class="hl-identifier">a_link</span><span class="hl-code">.</span><span class="hl-identifier">href</span><span class="hl-brackets">)
            </span><span class="hl-identifier">print_event_feed</span><span class="hl-brackets">(</span><span class="hl-identifier">event_feed</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:
    </span><span class="hl-identifier">username</span><span class="hl-default"> = </span><span class="hl-builtin">raw_input</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Enter your username: </span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">password</span><span class="hl-default"> = </span><span class="hl-identifier">getpass</span><span class="hl-default">.</span><span class="hl-identifier">getpass</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Enter your password: </span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

    </span><span class="hl-identifier">calendar_service</span><span class="hl-default"> = </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">calendar</span><span class="hl-default">.</span><span class="hl-identifier">service</span><span class="hl-default">.</span><span class="hl-identifier">CalendarService</span><span class="hl-brackets">(</span><span class="hl-identifier">username</span><span class="hl-code">
        , </span><span class="hl-identifier">password</span><span class="hl-code">
        , </span><span class="hl-quotes">&quot;</span><span class="hl-string">PythonMagazine-Calendar_Example-1.0</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-reserved">try</span><span class="hl-default">:
        </span><span class="hl-identifier">calendar_service</span><span class="hl-default">.</span><span class="hl-identifier">ProgrammaticLogin</span><span class="hl-brackets">()
    </span><span class="hl-reserved">except </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">service</span><span class="hl-default">.</span><span class="hl-identifier">BadAuthentication</span><span class="hl-default">, </span><span class="hl-identifier">e</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Authentication error logging in: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">e
        </span><span class="hl-reserved">return
    except Exception</span><span class="hl-default">, </span><span class="hl-identifier">e</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Error Logging in: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">e
        </span><span class="hl-reserved">return

    </span><span class="hl-identifier">list_own_calendars</span><span class="hl-brackets">(</span><span class="hl-identifier">calendar_service</span><span class="hl-brackets">)

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
    </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>An example of the output produced by Listing 5 can be seen in Listing 6. Don&#8217;t mind the formatting &#8211; it&#8217;s not pretty. It&#8217;s merely meant to give you an example of some of the data that you can mine from an event feed.</p>
<p><strong>Listing 6</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre>Mark Mruss's Calendar List
0) Mark Mruss - Summary: Main Calendar
	Authors:
		Mark Mruss
	Published: 2008-02-12T02:30:18.731Z
	Updated: 2008-02-08T04:03:10.000Z
	timezone: America/Toronto
	Colour: #5229A3
	Hidden: false
	Selected: true
	Access Level: owner
	Events:
	0) Dinner at the Drake
	Content: Dinner
		Who:
			Name: Mark Mruss
			email: mark.mruss@gmail.com
		Authors:
			Mark Mruss
		When:
			0) Start time: 2008-02-15T21:00:00.000-05:00
			End time: 2008-02-15T22:30:00.000-05:00
	1) Cezanne's Closet
	Content: Cezanne's Closet
		Who:
			Name: Mark Mruss
			email: mark.mruss@gmail.com
		Authors:
			Mark Mruss
		When:
			0) Start time: 2008-02-09
			End time: 2008-02-11</pre></div></div>
<h2>Adding an Event</h2>
<p>Adding a new event to a calendar is very similar to creating a new calendar. You need to create a new <code>CalendarEventEntry</code> instance. You then populate it with options, and pass it to the <code>CalendarService</code> classes <code>InsertEvent</code> function, along with the alternate link of the calendar to which you would like to add the event.</p>
<p>If you take a look at Listing 7 you can see a simple example of how to add an all day event. If you want to specify an event that lasts for less then a day, or include a specific start and end time, you need to use the &#8220;RFC 3339 timestamp&#8221; format for your <code>start_time</code> and <code>end_time</code> values. Also notice that just like adding a Calendar, the newly created event is returned by the <code>InsertEvent</code> function.</p>
<p><strong>Listing 7</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">a_link</span><span class="hl-default"> = </span><span class="hl-identifier">calendar</span><span class="hl-default">.</span><span class="hl-identifier">GetAlternateLink</span><span class="hl-brackets">()
</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">a_link </span><span class="hl-reserved">is not None</span><span class="hl-brackets">)</span><span class="hl-default">:

    </span><span class="hl-identifier">new_event</span><span class="hl-default"> = </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">calendar</span><span class="hl-default">.</span><span class="hl-identifier">CalendarEventEntry</span><span class="hl-brackets">()
    </span><span class="hl-identifier">new_event</span><span class="hl-default">.</span><span class="hl-identifier">title</span><span class="hl-default"> = </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">atom</span><span class="hl-default">.</span><span class="hl-identifier">Title</span><span class="hl-brackets">(</span><span class="hl-identifier">text</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">New Article</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">new_event</span><span class="hl-default">.</span><span class="hl-identifier">content</span><span class="hl-default"> = </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">atom</span><span class="hl-default">.</span><span class="hl-identifier">Content</span><span class="hl-brackets">(</span><span class="hl-identifier">text</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">Write Article</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">new_event</span><span class="hl-default">.</span><span class="hl-identifier">when</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">gdata</span><span class="hl-code">.</span><span class="hl-identifier">calendar</span><span class="hl-code">.</span><span class="hl-identifier">When</span><span class="hl-brackets">(
        </span><span class="hl-identifier">start_time</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">2008-02-20</span><span class="hl-quotes">&quot;</span><span class="hl-code">
        , </span><span class="hl-identifier">end_time</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">2008-02-21</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">))
    </span><span class="hl-reserved">try</span><span class="hl-default">:
        </span><span class="hl-identifier">created_event</span><span class="hl-default"> = </span><span class="hl-identifier">calendar_service</span><span class="hl-default">.</span><span class="hl-identifier">InsertEvent</span><span class="hl-brackets">(</span><span class="hl-identifier">new_event</span><span class="hl-code">
            , </span><span class="hl-identifier">a_link</span><span class="hl-code">.</span><span class="hl-identifier">href</span><span class="hl-brackets">)
    </span><span class="hl-reserved">except </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">service</span><span class="hl-default">.</span><span class="hl-identifier">RequestError</span><span class="hl-default">, </span><span class="hl-identifier">e</span><span class="hl-default">:
        </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Error adding event: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">e</span><span class="hl-brackets">[</span><span class="hl-number">0</span><span class="hl-brackets">][</span><span class="hl-quotes">&quot;</span><span class="hl-string">reason</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">])</span></pre></div></div>
<h2>Deleting an Event</h2>
<p>Deleting an event is (you guessed it) almost identical to deleting an entire calendar. This is because both helper functions wrap the same <code>GDataService</code> base class function. However the <code>'DeleteEvent</code> event function does a little bit more work than the <code>DeleteCalendarEntry</code> function by making sure that your <code>edit_uri</code> is in the correct format.</p>
<p>To delete an event you simply need to call the <code>DeleteEvent</code> function of the <code>CalendarService</code> class. An example of a function that will delete an event can be seen in Listing 8. This function takes a <code>CalendarService</code> instance and a <code>CalendarEventEntry</code> instance as parameters. As with the majority of these actions, the <code>CalendarService</code> instance should already be authenticated.</p>
<p><strong>Listing 8</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">delete_event</span><span class="hl-brackets">(</span><span class="hl-identifier">calendar_service</span><span class="hl-code">, </span><span class="hl-identifier">event</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">e_link</span><span class="hl-default"> = </span><span class="hl-identifier">event</span><span class="hl-default">.</span><span class="hl-identifier">GetEditLink</span><span class="hl-brackets">()
    </span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">e_link </span><span class="hl-reserved">is not None</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">try</span><span class="hl-default">:
            </span><span class="hl-identifier">calendar_service</span><span class="hl-default">.</span><span class="hl-identifier">DeleteEvent</span><span class="hl-brackets">(</span><span class="hl-identifier">e_link</span><span class="hl-code">.</span><span class="hl-identifier">href</span><span class="hl-brackets">)
        </span><span class="hl-reserved">except </span><span class="hl-identifier">gdata</span><span class="hl-default">.</span><span class="hl-identifier">service</span><span class="hl-default">.</span><span class="hl-identifier">RequestError</span><span class="hl-default">, </span><span class="hl-identifier">e</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Error deleting event: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">e</span><span class="hl-brackets">[</span><span class="hl-number">0</span><span class="hl-brackets">][</span><span class="hl-quotes">&quot;</span><span class="hl-string">reason</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">])</span></pre></div></div>
<h2>Conclusion</h2>
<p>Hopefully this article has given you a small taste of what is possible with the <code>gdata-python-client</code> module and Google Calendars. Maybe you can already imagine a use for these features in your next Python application? Please keep in mind that there is much more that can be done with Google Calendars, including updating existing Calendars and Events (<code>CalendarService</code> member functions: <code>UpdateCalendar</code> and <code>UpdateEvent</code>), and almost any other task you can perform using the &#8220;online&#8221; version of the Google Calendar service.</p>
<p>Also, it is important to note that the Python documentation for the Google Calendar service is sparse but growing. A lot of what is contained in this article was found through browsing the examples, the <code>gdata-python-client</code> source code, other people&#8217;s examples, as well as a whole bunch of trial and error on my part. Since this is the case, there may be other ways, or more preferred methods of accomplishing what I have shown here.</p>
<p><a href="http://code.google.com/p/gdata-python-client/">[1] http://code.google.com/p/gdata-python-client/</a><br />
<a href="http://code.google.com/apis/gdata/index.html">[2] http://code.google.com/apis/gdata/index.html</a><br />
<a href="http://code.google.com/p/gdata-python-client/">[3] http://code.google.com/p/gdata-python-client/</a><br />
<a href="http://code.google.com/apis/calendar/developers_guide_python.html">[4] http://code.google.com/apis/calendar/developers_guide_python.html</a><br />
<a href="http://code.google.com/apis/calendar/reference.html">[5] http://code.google.com/apis/calendar/reference.html</a><br />
<a href="http://www.google.com/calendar">[6] http://www.google.com/calendar</a><br />
<a name="7">[7] gdata.calendar.service.py (From the source comments)</a><br />
<a name="8">[8] gdata.service.py (From the source comments)</a><br />
<a href="http://code.google.com/apis/accounts/AuthForInstalledApps.html">[9] http://code.google.com/apis/accounts/AuthForInstalledApps.html</a><br />
<a href="http://code.google.com/apis/calendar/developers_guide_python.html">[10] http://code.google.com/apis/calendar/developers_guide_python.html</a><br />
</ns0></p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2010/02/27/an-introduction-to-google-calendars/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Introducing Docstrings</title>
		<link>http://www.learningpython.com/2010/01/08/introducing-docstrings/</link>
		<comments>http://www.learningpython.com/2010/01/08/introducing-docstrings/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 03:41:06 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[Python Magazine]]></category>
		<category><![CDATA[docstrings]]></category>
		<category><![CDATA[PythonMagazine]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=118</guid>
		<description><![CDATA[By: Mark Mruss Note: This article was first published the February 2008 issue of Python Magazine Of all the tasks assigned to programmers, commenting code and writing documentation are among the most disliked. This article introduces you to Python&#8217;s documentation strings. While they won&#8217;t make commenting your code any more enjoyable, they will provide a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F01%2F08%2Fintroducing-docstrings%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F01%2F08%2Fintroducing-docstrings%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>By: Mark Mruss</strong></p>
<p><strong>Note:</strong> This article was first published the <a href="http://www.pythonmagazine.com/c/issue/view/66">February 2008 issue</a> of <a href="http://www.pythonmagazine.com">Python Magazine</a></p>
<p>Of all the tasks assigned to programmers, commenting code and writing documentation are among the most disliked.  This article introduces you to Python&#8217;s documentation strings. While they won&#8217;t make commenting your code any more enjoyable, they will provide a systematic approach to doing it, as well as access to additional tools for documentation generation and testing.</p>
<p></p>
<p><span id="more-118"></span></p>
<p>You&#8217;ve just finished your new Python module. You can&#8217;t wait to upload it to the Web and let all the other Python hackers start using it. The only step left is the most dreaded for many programmers: documentation. Unless you&#8217;ve been commenting and documenting your code as you wrote it, you&#8217;re going to have to go back through each source file, class, and function, trying to remember exactly what your code was supposed to do. Not an enjoyable task.</p>
<p>Sound familiar to you? If it does, you&#8217;re probably not using documentation strings, commonly known as doc strings or docstrings (I prefer docstrings, without the space), or any of the handy tools that work with docstrings. This article will introduce you to Python&#8217;s docstrings, and a few of the tools that make them a great addition to your code.</p>
<h2>Docstrings</h2>
<p>If you are not already using docstrings in your Python code, you really should. They provide a standard way to comment your code, giving you and other developers (who might want to use your code at some point) easy access to descriptions of the modules, classes, and functions found within.</p>
<p>At the heart of it, docstrings are simply comments placed in special locations in your Python source code. These comments can then be looked at by tools designed to work with docstrings or other Python programmers using your code. Note that I said using// your code, not reading your code. This is because docstrings are accessible via a Python object&#8217;s <code>__doc__</code> attribute. This is very helpful is you are testing out a new module in Python&#8217;s interactive shell and really need to know what sort of parameters a certain function needs.</p>
<p>Pep 257 has a good definition of docstrings: &#8220;A docstring is a string literal that occurs as the first statement in a module, function, class, or method definition. Such a docstring becomes the __doc__ special attribute of that object.&#8221;<a href="#1">[1]</a>  Definitions are nice but it might be easier to look at a quick example of some docstrings:</p>
<div class="hl-surround" ><div class="hl-main"><pre>def add(x, y):
    &quot;&quot;&quot;This is the add function's docstring.&quot;&quot;&quot;
	return x + y</pre></div></div>
<div class="hl-surround" ><div class="hl-main"><pre>def subtract(x, y):
    &quot;&quot;&quot;This is the subtract function's docstring.
    It is longer then the add functions, it goes
    on and on and on and on.&quot;&quot;&quot;
    return x - y</pre></div></div>
<p>Since docstrings are comments they can be in any format that you want, however since this is Python there are a few style guidelines that you should probably be aware of. You don&#8217;t have to follow these guidlines but if you do it will be easier for other Python programmers to understand and work with your code.</p>
<p>In general there are two types of docstrings: one-line docstrings and multi-line docstrings. The difference between the two should be fairly obvious: one-line docstrings are only one line in length and multi-line docstrings are more then one line in length. One-line docstrings and multi-line docstrings each have different style guidelines that will be explained in more detail in the following two sections.</p>
<h2>One-Line Docstrings</h2>
<p>Let&#8217;s look at a quick example of a one-line docstring for a simple function:</p>
<div class="hl-surround" ><div class="hl-main"><pre>def add(x, y):
    &quot;&quot;&quot;Return the sum of two numbers.&quot;&quot;&quot;
    return x + y</pre></div></div>
<p>In this example <code>"""Return the sum of two numbers."""</code> is the docstring of the <code>add</code> function. If you were to run the following:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>print add.__doc__</pre></div></div>
<p>The output would look like this:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>Return the sum of two numbers.</pre></div></div>
<p>In his &#8220;Python Style Guide&#8221; Guido van Rossum has a few notes on the preferred style of one line docstrings:</p>
<ul>
<li>Triple quotes are used even though the string fits on one line. This makes it easy to later expand it.</li>
<li>The closing quotes are on the same line as the opening quotes. This looks better for one-liners.</li>
<li>There&#8217;s no blank line either before or after the doc string.</li>
<li>The doc string is a phrase ending in a period. It prescribes the function&#8217;s effect as a command (&#8220;<strong>Do</strong> this&#8221;, &#8220;<strong>Return</strong> that&#8221;), not as a description: e.g. don&#8217;t write &#8220;Returns the pathname &#8230;&#8221; <a href="#2">[2]</a></li>
</ul>
<p>One-line docstrings should only be used to document the simplest of cases. If what you are documenting does anything complicated, accepts input, or returns a value, it&#8217;s probably a good idea to use a multi-line docstring.</p>
<h2>Multi-Line Docstrings</h2>
<p>Multi-line docstrings should be used to document the majority of your modules, classes, functions, and methods. This is because most of what you are programming performs tasks more complicated then that which can fit into a single sentence summary. Multi-line docstrings should be used to documents the input, output, and complex behaviour of your objects. Like one-line docstrings, multi-line docstrings should start with a single sentence summary. After that there should be a blank line and then a more detailed description. The blank line separating the one line summary and the additional information is important as certain tools will use the blank line to separate the summary from the rest of the docstring. An example of a multi-line comment can be found in Listing 1.</p>
<p><strong>Listing 1</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">subtract</span><span class="hl-brackets">(</span><span class="hl-identifier">x</span><span class="hl-code">, </span><span class="hl-identifier">y</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Return the difference between two numbers.

    Arguments:
    x -- The minuend.
    y -- The subtrahend.

    Returns:
    A number, the difference between x and y (ie. x - y)

    </span><span class="hl-quotes">&quot;&quot;&quot;
    </span><span class="hl-reserved">return </span><span class="hl-identifier">x</span><span class="hl-default"> - </span><span class="hl-identifier">y</span></pre></div></div>
<h2>What to Document</h2>
<p>There are also style guidelines that dictate what you should include in your multi-line docstrings when documenting different sections of your code. These are general guidelines but following them will help ensure that your code is well documented and easily understood by other Python programmers. For more information on this please see Guido&#8217;s &#8220;Python Style Guide&#8221;.<a href="#2">[2]</a></p>
<p><strong>Modules</strong> &#8211; Document the module and provide a one line summary of everything that is exported by the module. (eg. classes, exceptions, and functions).</p>
<p><strong>Classes</strong> &#8211; Summarize the functionality of the class. List all public methods and data members of the class. If there is any addition information needed to subclass the class, or if there is an additional interface for subclasses provide a description.</p>
<p><strong>Functions and Methods</strong> &#8211; Summarize the functionality of the function and &#8220;document its arguments, return value(s), side effects, exceptions raised, and restrictions on when it can be called (all if applicable).&#8221;<a href="#3">[3]</a></p>
<p>An example of all of these can be found in Listing 2.</p>
<p><strong>Listing 2</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">A simple math module.

Exported Classes:

Math -- A simple math class with mathematical functions.

</span><span class="hl-quotes">&quot;&quot;&quot;

</span><span class="hl-reserved">class </span><span class="hl-identifier">Math</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">A simple math class with mathematical functions.

    Public functions:
    add -- Adds two numbers together and
    returns the result.

    subtract -- Returns the difference between
    two numbers.

    </span><span class="hl-quotes">&quot;&quot;&quot;

    </span><span class="hl-reserved">def </span><span class="hl-identifier">subtract</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">x</span><span class="hl-code">, </span><span class="hl-identifier">y</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Return the difference between two numbers.

        Arguments:
        x -- The minuend.
        y -- The subtrahend.

        Returns:
        A number, the difference between x and y (ie. x - y)

        </span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-reserved">return </span><span class="hl-identifier">x</span><span class="hl-default"> - </span><span class="hl-identifier">y

    </span><span class="hl-reserved">def </span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">x</span><span class="hl-code">, </span><span class="hl-identifier">y</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Return the sum of two numbers.

        Arguments:
        x -- Number to be summed.
        y -- Number to be summed.

        Returns:
        A number, the sum of x and y (ie. x + y)

        </span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-reserved">return </span><span class="hl-identifier">x</span><span class="hl-default"> + </span><span class="hl-identifier">y</span></pre></div></div>
<h2>Documentation Generation</h2>
<p>Generally if you have a complicated module or API people would rather read a help file, or online documentation, as opposed to constantly having find and browse the source code. Thankfully for us there are many different documentation generation tools out there that make use of docstrings. So when you are writing your docstrings, you aren&#8217;t just commenting your source code you&#8217;re also writing your help file!</p>
<p>The easiest tool to use is PyDoc, it&#8217;s a module, and a stand-alone application, that has been included in the Python standard library since version 2.1. There is much that can be done with PyDoc but for this column we are going to focus on it&#8217;s documentation generation. PyDoc can take the docstrings found within a module and output them as either simple text documentation (much like UNIX or Linux man pages) or HTML documentation.</p>
<p>Creating HTML documentation of the <code>SimpleMath</code> module used in Listing 2 is very easy. On a UNIX like computer (Linux, OS X, etc.) it can be accomplished using the following command:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>$ pydoc -w /home/selsine/python/SimpleMath.py</pre></div></div>
<p>On Windows the command will look something like this:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>C:&gt;c:Python25Libpydoc.py -w c:pythonSimpleMath.py</pre></div></div>
<p>This will create an HTML file named <code>SimpleMath.html</code> in the current folder. A sample of what the generated HTML looks like can be seen in Figure 1. </p>
<div id="attachment_124" class="wp-caption alignnone" style="width: 462px"><img src="http://www.learningpython.com/wp-content/uploads/2010/01/firgure1.png" alt="Figure 1 - pydoc" title="Figure 1 - pydoc" width="452" height="538" class="size-full wp-image-124" /><p class="wp-caption-text">Figure 1 - pydoc</p></div>
<p>While PyDoc is a great tool and easy to use because it is in the standard library, there are a few other tools out there that you might consider using. If you look at the HTML file that PyDoc generates you will notice that it does not mark up your docstrings. It simply reads them from your source code and spits them back out. If you are looking for something a little bit fancier with a few more options you might consider Epydoc<a href="#4">[4]</a> or docutils<a href="#5">[5]</a>.</p>
<p>Both Epydoc and docutils use simple markup languages to give the documentation generated a bit more punch. Docutils uses the reStructuredText markup language. While Epydoc uses the Epytext markup language, as well as being able to work with Javadoc and reStructuredText. An example of the HTML that Epydoc produces can be seen in Figure 2. The code that was used to generate the HTML can be found in Listing 3.</p>
<p><img src="http://www.learningpython.com/wp-content/uploads/2010/01/firgure2.png" alt="Figure 2 - Epydoc" title="Figure 2 - Epydoc" class="alignnone size-full wp-image-125" /><br />
Figure 2 &#8211; Epydoc</p>
<p><strong>Listing 3</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">A simple math module.

Exported Classes:

Math -- A simple math class with mathematical functions.

</span><span class="hl-quotes">&quot;&quot;&quot;

</span><span class="hl-reserved">class </span><span class="hl-identifier">Math</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">A simple math class with mathematical functions.

    Public functions:
    add -- Adds two numbers together and
    returns the result.

    subtract -- Returns the difference between
    two numbers.

    </span><span class="hl-quotes">&quot;&quot;&quot;

    </span><span class="hl-reserved">def </span><span class="hl-identifier">subtract</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">x</span><span class="hl-code">, </span><span class="hl-identifier">y</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Return the difference between two numbers.

        @type   x: number
        @param  x: The minuend.
        @type   y: number
        @param  y: The subtrahend.

        @rtype: number
        @returns: A number, the difference between x and y (ie. x - y)

        </span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-reserved">return </span><span class="hl-identifier">x</span><span class="hl-default"> - </span><span class="hl-identifier">y

    </span><span class="hl-reserved">def </span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">x</span><span class="hl-code">, </span><span class="hl-identifier">y</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Return the sum of two numbers.

        @type   x: number
        @param  x: Number to be summed.
        @type   y: number
        @param  y: Number to be summed.

        @rtype: number
        @returns: A number, the sum of x and y (ie. x + y)

        </span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-reserved">return </span><span class="hl-identifier">x</span><span class="hl-default"> + </span><span class="hl-identifier">y

</span><span class="hl-reserved">def </span><span class="hl-identifier">_test</span><span class="hl-brackets">()</span><span class="hl-default">:
    </span><span class="hl-reserved">import </span><span class="hl-identifier">doctest
    doctest</span><span class="hl-default">.</span><span class="hl-identifier">testmod</span><span class="hl-brackets">()

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
    </span><span class="hl-identifier">_test</span><span class="hl-brackets">()</span></pre></div></div>
<h2>Doctest</h2>
<p>One of the most interesting uses of docstrings is unit testing using the <code>doctest</code> module. As we all know testing our code is important, and (as many of us have begun to learn) writing unit tests for large projects is a great way to ensure that changes in one area of a project don&#8217;t cause problems elsewhere in the code. If you don&#8217;t know what a unit test is it&#8217;s basically a simple test case to prove whether a specific area of your code is functioning properly. Generally at least one unit test is created for each object in order to test the correctness of the project as a whole.</p>
<p>In a nutshell the the doctest<code> module searches your dostrings "for pieces of text that look like interactive Python sessions, and then executes those sessions to verify that they work exactly as shown."<a href="#6">[6]</a> This means that it will search your docstrings for lines that start with </code><code>>>></code> or with <code>...</code> if they are the continuation of a statement (i.e. the inside of a function).  If there is output generated by the statements it &#8220;must immediately follow the final &#8216;>>> &#8216; or &#8216;&#8230; &#8216; line containing the code, and &#8230; extends to the next &#8216;>>> &#8216; or all-whitespace line.&#8221;<a href="#7">[7]</a> Adding doctests doesn&#8217;t just add unit tests to your code it also provides working examples in your docstrings and documentation.</p>
<p>Since doctests are formatted to look like interactive Python sessions a simple way to write them is to use Python&#8217;s interactive shell. You do this by simply executing your code in the interactive shell, and then copying and pasting the resulting test into your docstrings. For example, if we were to use this method to write a doctest for our subtract method we could do something like the following in the interactive shell:</p>
<div class="hl-surround" ><div class="hl-main"><pre>&gt;&gt;&gt; from SimpleMath import Math
&gt;&gt;&gt; simple_math = Math()
&gt;&gt;&gt; simple_math.subtract(10, 7)
3
&gt;&gt;&gt;</pre></div></div>
<p>We don&#8217;t need to import our module for the doctest so all we will need to copy from the interactive shell are the middle three lines:</p>
<div class="hl-surround" ><div class="hl-main"><pre>&gt;&gt;&gt; simple_math = Math()
&gt;&gt;&gt; simple_math.subtract(10, 7)
3</pre></div></div>
<p>As you can see, what we have here is a test compromising of two lines of Python code and then the expected result. The <code>SimpleMath</code> module containing a doctest for each function can be found in Listing 4.</p>
<p><strong>Listing 4</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python
</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">A simple math module.

Exported Classes:

Math -- A simple math class with mathematical functions.

</span><span class="hl-quotes">&quot;&quot;&quot;

</span><span class="hl-reserved">class </span><span class="hl-identifier">Math</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">A simple math class with mathematical functions.

    Public functions:
    add -- Adds two numbers together and
    returns the result.

    subtract -- Returns the difference between
    two numbers.

    </span><span class="hl-quotes">&quot;&quot;&quot;

    </span><span class="hl-reserved">def </span><span class="hl-identifier">subtract</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">x</span><span class="hl-code">, </span><span class="hl-identifier">y</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Return the difference between two numbers.

        &gt;&gt;&gt; simple_math = Math()
        &gt;&gt;&gt; simple_math.subtract(10, 7)
        3

        @type   x: number
        @param  x: The minuend.
        @type   y: number
        @param  y: The subtrahend.

        @rtype: number
        @returns: A number, the difference between x and y (ie. x - y)

        </span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-reserved">return </span><span class="hl-identifier">x</span><span class="hl-default"> - </span><span class="hl-identifier">y

    </span><span class="hl-reserved">def </span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">x</span><span class="hl-code">, </span><span class="hl-identifier">y</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Return the sum of two numbers.

        &gt;&gt;&gt; simple_math = Math()
        &gt;&gt;&gt; simple_math.add(10, 7)
        17

        @type   x: number
        @param  x: Number to be summed.
        @type   y: number
        @param  y: Number to be summed.

        @rtype: number
        @returns: A number, the sum of x and y (ie. x + y)

        </span><span class="hl-quotes">&quot;&quot;&quot;
        </span><span class="hl-reserved">return </span><span class="hl-identifier">x</span><span class="hl-default"> + </span><span class="hl-identifier">y

</span><span class="hl-reserved">def </span><span class="hl-identifier">_test</span><span class="hl-brackets">()</span><span class="hl-default">:
    </span><span class="hl-reserved">import </span><span class="hl-identifier">doctest
    doctest</span><span class="hl-default">.</span><span class="hl-identifier">testmod</span><span class="hl-brackets">()

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
    </span><span class="hl-identifier">_test</span><span class="hl-brackets">()</span></pre></div></div>
<p>If you look at Listing 4 you will also notice the following code at the end of the source:</p>
<div class="hl-surround" ><div class="hl-main"><pre>def _test():
    import doctest
    doctest.testmod()

if __name__ == &quot;__main__&quot;:
    _test()</pre></div></div>
<p>This is the code that will be executed if the module is launched directly from the command line. The code will import the <code>doctest</code> module and then use the <code>testmod</code> method to test the current module. Now when we run our <code>SimpleMath.py</code> file directly we will get the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre>$ python SimpleMath.py
$</pre></div></div>
<p>Since nothing was written out to the command line we know that all of the doctests were successful. If you want to get more information you can use the -v<code> flag to produce verbose output:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>$ python SimpleMath.py -v</pre></div></div>
<p>If you were to encounter an error it would look something like Listing 5.</p>
<p><strong>Listing 5</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre>**********************************************************************
File &quot;SimpleMath.py&quot;, line 26, in __main__.Math.subtract
Failed example:
    simple_math.subtract(10, 7)
Expected:
    4
Got:
    3
**********************************************************************
1 items had failures:
   1 of   2 in __main__.Math.subtract
***Test Failed*** 1 failures.</pre></div></div>
<p>As an added bonus if you are using Epydoc or docutils to generate your documentation, both tools will recognize doctest sections and highlight them. An example of what it looks like when Epydoc does this can be seen in Figure 3.</p>
<div id="attachment_129" class="wp-caption alignnone" style="width: 310px"><img src="http://www.learningpython.com/wp-content/uploads/2010/01/firgure3-300x115.png" alt="Figure 3 - doctest" title="Figure 3 - doctest" width="300" height="115" class="size-medium wp-image-129" /><p class="wp-caption-text">Figure 3 - doctest</p></div>
<h2>Conclusion</h2>
<p>Hopefully by this point you can see how useful docstrings can be to any Python code that you write. They give you a structured way to document your source code, the ability to easily generate great looking documentation, and a simple way to add unit tests to your code. But that's not all, as more and more people start using doctrings you can be sure that the list of docstring tools will continue to grow.</p>
<p>We all know that commenting source code and writing documentation are among the least enjoyable tasks a programmer can face. In fact the only thing worse then commenting and documenting is trying to use code with no comments and poor documentation! So do me, and yourself, a favour: start writing those docstrings.</p>
<p><a name="1">[1] http://www.python.org/dev/peps/pep-0257/#what-is-a-docstring</a><br />
<a name="2">[2] http://www.python.org/doc/essays/styleguide.html</a><br />
<a name="3">[3] http://www.python.org/doc/essays/styleguide.html</a><br />
<a name="4">[4] http://epydoc.sourceforge.net/</a><br />
<a name="5">[5] http://docutils.sourceforge.net/</a><br />
<a name="6">[6] http://docs.python.org/lib/module-doctest.html</a><br />
<a name="7">[7] http://docs.python.org/lib/doctest-finding-examples.html</a></code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2010/01/08/introducing-docstrings/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Iterators, Iterables, and Generators! Oh, my!</title>
		<link>http://www.learningpython.com/2009/02/23/iterators-iterables-and-generators-oh-my/</link>
		<comments>http://www.learningpython.com/2009/02/23/iterators-iterables-and-generators-oh-my/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 13:32:52 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[Python Magazine]]></category>
		<category><![CDATA[Generators]]></category>
		<category><![CDATA[Iterables]]></category>
		<category><![CDATA[Iterators]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=110</guid>
		<description><![CDATA[By: Mark Mruss Note: This article was first published the January 2008 issue of Python Magazine Iterators, iterables, and generators are features handled so wall by Python that people programming in other languages cannot help but drool over. Fortunately for us, creating iterators, iterables and generators is a relatively simple task. This article introduces the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2009%2F02%2F23%2Fiterators-iterables-and-generators-oh-my%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2009%2F02%2F23%2Fiterators-iterables-and-generators-oh-my%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>By: Mark Mruss</strong></p>
<p><strong>Note:</strong> This article was first published the <a href="http://www.pythonmagazine.com/c/issue/view/66">January 2008 issue</a> of <a href="http://www.pythonmagazine.com">Python Magazine</a></p>
<p>Iterators, iterables, and generators are features handled so wall by Python that people programming in other languages cannot help but drool over. Fortunately for us, creating iterators, iterables and generators is a relatively simple task. This article introduces the concepts of iterators, iterables, and generators and illustrates how easy it is to add them to your code.</p>
<ol>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#IterationInPython">Iteration in Python</a></li>
<li><a href="#AnInitialExample">An Initial Example</a></li>
<li><a href="#CreatingAnIterator">Creating An Iterator</a></li>
<li><a href="#LookingMoreCloselyAtTheIterator">Looking More Closely At The Iterator</a></li>
<li><a href="#TheUpsideAndDownsideOfIterators">The Upside And Downside Of Iterators</a></li>
<li><a href="#Generators">Generators</a></li>
<li><a href="#LookingCloselyAtTheGenerator">Looking Closely At The Generator</a></li>
<li><a href="#ButWhatAboutIterables">But What About Iterables?</a></li>
<li><a href="#CreatingAnIterableObject">Creating An Iterable Object</a></li>
<li><a href="#Conclusion">Conclusion</a></li>
</ol>
<p><span id="more-110"></span></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>In this article I&#8217;m going to introduce three related Python features: iterators, iterables, and generators. Generators are easy to define, they are functions that create and return an iterator. Iterators and iterables on the other hand, are easier to use than they are to define. An iterable object is a &#8220;container object capable of returning its members one at a time.&#8221;[1] An iterator object is &#8220;An object representing a stream of data. Repeated calls to the iterator&#8217;s next() method return successive items in the stream. When no more data is available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its next() method just raise StopIteration again.&#8221;<a href="#1">[1]</a> You can think of the difference between the two in this way: an iterable object can be iterated over multiple times, whereas an iterator object can only be iterated over once. In general an iterable produces an iterator every time something wants to iterate over its data. </p>
<p><strong>Note:</strong> Classes that define the <code>__getitem__</code> function are also considered iterables, but since that falls outside the scope of this article, it will not be covered here.</p>
<p>In this tutorial, I will begin by discussing iterators, the most basic concept. Then I will move onto generators, and finish by discussing iterables, the most wide open topic of the three.</p>
<h2><a name="IterationInPython">Iteration in Python</a></h2>
<p>Iterators objects are used in Python in order to iterate over an objects data. For example, we all know how to do this in Python when we work with lists:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">my_list</span><span class="hl-default"> = </span><span class="hl-brackets">[</span><span class="hl-number">1</span><span class="hl-code">,</span><span class="hl-number">2</span><span class="hl-code">,</span><span class="hl-number">3</span><span class="hl-brackets">]
</span><span class="hl-reserved">for </span><span class="hl-identifier">num </span><span class="hl-reserved">in </span><span class="hl-identifier">my_list</span><span class="hl-default">:
	</span><span class="hl-reserved">print </span><span class="hl-identifier">num</span></pre></div></div>
<p>This code will iterate over the list object <code>my_list</code> and print out all of the list items , i.e., the numbers 1, 2, and 3. Iterating over sequences in this simple and transparent manner happens to be one of my favourite features of Python. </p>
<p>According to our definition above, lists are iterables since you can iterate over them multiple times. In fact, each time you iterate over a list you are actually using a listiterator iterator object produced by the list.</p>
<p>It may not be immediately clear to you when you should add an iteration support to a class. However, the more you work with Python the more you&#8217;ll find instances when doing just this is very useful, sometimes the only advantage is cleaner looking code. One nice thing about iterators (and generators too) is that the processing for each item happens as you need it.  Instead of collecting all of the data into a list and then running through the list, you will collect each item as you need it. This might not seem like a large difference but imagine if there were tens of thousands of items to process? What if you were collection your data from an online source? Performing all of your processing up front may take a very long time, especially if you only wanted the first few items.</p>
<h2><a name="AnInitialExample">An initial example</a></h2>
<p>In order to explain iteration further, let&#8217;s look at a simple example task where we might use iterators. For this example we will create a class that takes a string of characters as input and then converts each character into its byte value.  If we were <strong>NOT</strong> going to use iterators we might do something like what is found in Listing 1.</p>
<p><strong>Listing 1</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">data</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default"> = </span><span class="hl-identifier">data

	</span><span class="hl-reserved">def </span><span class="hl-identifier">to_bytes</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">bytes</span><span class="hl-default"> = </span><span class="hl-brackets">[]
		</span><span class="hl-reserved">for </span><span class="hl-identifier">char </span><span class="hl-reserved">in </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default">:
			</span><span class="hl-identifier">bytes</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">char</span><span class="hl-brackets">))
		</span><span class="hl-reserved">return </span><span class="hl-identifier">bytes</span></pre></div></div>
<p>This code is pretty simple. We have a data member, named <code>data</code>, that we use to store the string that was used to initialize the class. In the <code>to_bytes</code> function we loop through the string, converting each character to its byte value using the built in <code>ord</code> function. We store each byte value in a list and once we have collected all of the values we return that list.</p>
<p>When we run the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">for </span><span class="hl-identifier">byte </span><span class="hl-reserved">in </span><span class="hl-identifier">bv</span><span class="hl-default">.</span><span class="hl-identifier">to_bytes</span><span class="hl-brackets">()</span><span class="hl-default">:
	</span><span class="hl-reserved">print </span><span class="hl-identifier">byte</span></pre></div></div>
<p>we would get this as our output:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-number">97
98
99
100
101
102</span></pre></div></div>
<h2><a name="CreatingAnIterator">Creating an Iterator</a></h2>
<p>Let&#8217;s convert this into an iterator. Making your class into an iterator requires adding &#8220;two methods, which together form the iterator protocol.&#8221;<a href="#2">[2]</a> The two functions needed are: 1) the <code>__iter__</code> function; and, 2) the <code>next</code> function. The <code>__iter__</code> function will return the object itself, while the <code>next</code> function will return the next item. The <code>next</code> function is where the actual iteration work occurs. The <code>next</code> function iterates by returning the next item in the &#8220;sequence&#8221; each time it is called for as long as there is a &#8220;next&#8221; item.  When there are no more items to iterate over, the <code>next</code> function must raise the <code>StopIteration</code> exception to halt the iteration.</p>
<p>To be clear, in order to make your class an iterator you need to do two things:</p>
<p><strong>1)</strong> Add an <code>__iter__</code> function that returns the object itself (<code>self</code>)</p>
<p><strong>2)</strong> Add a <code>next</code> function that returns the next item in the sequence each time it is called. When there are no more items in the sequence, the <code>next</code> function raises a <code>StopIteration</code> exception signal the end of the iteration. </p>
<p>For those of you still confused, the following example will help illustrate how iterators work. If we were to convert our ByteValue class into an iterator object, it might look something like Listing 2.</p>
<p><strong>Listing 2</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">data</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default"> = </span><span class="hl-identifier">data
		self</span><span class="hl-default">.</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-number">0

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__iter__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-reserved">return </span><span class="hl-identifier">self

	</span><span class="hl-reserved">def </span><span class="hl-identifier">next</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">current_item</span><span class="hl-code"> == </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-reserved">raise StopIteration
		else</span><span class="hl-default">:
			</span><span class="hl-identifier">byte_value</span><span class="hl-default"> = </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">current_item</span><span class="hl-default"> += </span><span class="hl-number">1
			</span><span class="hl-reserved">return </span><span class="hl-identifier">byte_value</span></pre></div></div>
<p>Let&#8217;s compare the code in Listings 1 and Listing 2 in detail, focusing on the iterator in Listing 2.  The first difference is the addition of the data member <code>current_item</code> to the class, initialized in the <code>__init__</code> function.  <code>current_item</code> serves as a counter and keeps track of the current character in the string while we iterate over it.  The counter must have class scope since the iterator works through successive calls to the <code>next</code> function.  If <code>current_item</code> were local to the <code>next</code> function, its value would be reset with each subsequent call, and would not be of much use.</p>
<p>The second difference between the listings is the addition in Listing 2, of the <code>__iter__</code> function where we return <code>self</code>.</p>
<p>The final addition to Listing 2 is the <code>next</code> function, where we first check to see if <code>current_item</code> is equal to the length of our string.  If <code>current_item</code> is equal to the strings length we raise the <code>StopIteration</code> exception to signal the end of the iteration because we have no more characters left to iterate over. If there are more characters to iterate over we calculate the byte value of the current character, increase our <code>current_item</code> counter, and then return the byte value.</p>
<p><strong>Note:</strong> Notice that <code>current_item</code> is only initialized when the ByteValue object is created. This happens because according to the iteration protocol, &#8220;once an iterator&#8217;s next() method raises StopIteration, it will continue to do so on subsequent calls.&#8221;<a href="#2">[2]</a> If we were to re-initialize <code>current_item</code> we would then be able to iterate over the iterator more than once breaking the iteration protocol.</p>
<p>Now that we have converted our class into an iterator we can use it as follows:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">for </span><span class="hl-identifier">byte </span><span class="hl-reserved">in </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-reserved">print </span><span class="hl-identifier">byte</span></pre></div></div>
<p>Doing so would result in:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-number">97
98
99
100
101
102</span></pre></div></div>
<p>Notice that we do not store the instance of our ByteValue class in a variable. Doing so would be useless because since ByteValue is an iterator it is only good for one pass of the data. If ByteValue were an iterable (returning an iterator object when <code>__iter__</code> was called) it would make sense to keep an instance around because we could iterate over the instance more than once. We will look at creating iterables later on in this article. </p>
<h2><a name="LookingMoreCloselyAtTheIterator">Looking more closely at the Iterator</a></h2>
<p>Let&#8217;s look at what is happening in more detail by examining what is happening behind the scenes during the iteration process. In order to illustrate what is happening in the for loop I will demonstrate the order in which things are being called behind the scenes.  </p>
<p>The first step in the iteration process is to call to the <code>__iter__</code> function in order to get the iterator object that will perform the iteration. Notice that this works on iterator and iterable objects, since iterators returns themselves and iterables return an iterator.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">iterator</span><span class="hl-default"> = </span><span class="hl-identifier">bv</span><span class="hl-default">.</span><span class="hl-identifier">__iter__</span><span class="hl-brackets">()</span></pre></div></div>
<p>Now that we have the iterator object, we start iterating by calling the <code>next</code> function in order to get the next value:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()</span></pre></div></div>
<p>This executes the <code>next</code> function which will return the byte value of character in the string with which we are currently working. Since this is the first call to the <code>next</code> function <code>current_item</code> will be zero and we will calculate the byte value of the first character in our string (&#8216;a&#8217;) resulting in:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-number">97</span></pre></div></div>
<p>If we continue the iteration process by calling the <code>next</code> function six more times we would get the results shown in Listing 3. Notice that we have now made a total of seven calls to the <code>next</code> function, one more then the number of characters in our string. I&#8217;m running the python code from a file (iter.py found in Listing 4). Depending on how you are running it, you might get slightly different results. However, the most important thing to observe in this example is the exception that is raised.</p>
<p><strong>Listing 3</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-number">97
98
99
100
101
102
</span><span class="hl-identifier">Traceback </span><span class="hl-brackets">(</span><span class="hl-identifier">most recent call last</span><span class="hl-brackets">)</span><span class="hl-default">:
  </span><span class="hl-identifier">File </span><span class="hl-quotes">&quot;</span><span class="hl-string">Listing4.py</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-identifier">line </span><span class="hl-number">34</span><span class="hl-default">, </span><span class="hl-reserved">in</span><span class="hl-default"> ?
    </span><span class="hl-identifier">main</span><span class="hl-brackets">()
  </span><span class="hl-identifier">File </span><span class="hl-quotes">&quot;</span><span class="hl-string">Listing4.py</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-identifier">line </span><span class="hl-number">30</span><span class="hl-default">, </span><span class="hl-reserved">in </span><span class="hl-identifier">main
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
  </span><span class="hl-identifier">File </span><span class="hl-quotes">&quot;</span><span class="hl-string">Listing4.py</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-identifier">line </span><span class="hl-number">13</span><span class="hl-default">, </span><span class="hl-reserved">in </span><span class="hl-identifier">next
    </span><span class="hl-reserved">raise StopIteration
StopIteration</span></pre></div></div>
<p><strong>Listing 4</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python

</span><span class="hl-reserved">class </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">data</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default"> = </span><span class="hl-identifier">data
		self</span><span class="hl-default">.</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-number">0
	</span><span class="hl-reserved">def </span><span class="hl-identifier">__iter__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-reserved">return </span><span class="hl-identifier">self

	</span><span class="hl-reserved">def </span><span class="hl-identifier">next</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">current_item</span><span class="hl-code"> == </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-reserved">raise StopIteration
		else</span><span class="hl-default">:
			</span><span class="hl-identifier">byte_value</span><span class="hl-default"> = </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">current_item</span><span class="hl-default"> += </span><span class="hl-number">1
			</span><span class="hl-reserved">return </span><span class="hl-identifier">byte_value
		</span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data

</span><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:
    </span><span class="hl-reserved">for </span><span class="hl-identifier">v </span><span class="hl-reserved">in </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abc</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">if </span><span class="hl-identifier">v </span><span class="hl-reserved">in </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abc</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">We have a %d</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">v

    bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-identifier">iterator</span><span class="hl-default"> = </span><span class="hl-identifier">bv</span><span class="hl-default">.</span><span class="hl-identifier">__iter__</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
    </span><span class="hl-reserved">print </span><span class="hl-identifier">iterator</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
	</span><span class="hl-comment"># Someone is launching this directly
	</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>For the most part you won&#8217;t be calling an iterator object&#8217;s <code>__iter__</code> or <code>next</code> functions manually, instead you&#8217;ll probably just let the for loop do it all for you.</p>
<h2><a name="TheUpsideAndDownsideOfIterators">The upside and downside of Iterators</a></h2>
<p>Now that our class is an iterator object we can use any of the built-in functions and methods that work on iterators and iterables, such as: the <code>sum</code>, <code>tuple</code>, <code>sorted</code>, and <code>list</code> functions, to name a few.</p>
<p>In the first example the <code>bytes</code> function returned a list object that we could work with. If we want a list instead of an iterator for any reason, it will be as simple as using the <code>list</code> function, which takes an iterator as a parameter and returns a list:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-builtin">list</span><span class="hl-brackets">(</span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">))</span></pre></div></div>
<p>If we want a sorted list:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">sorted</span><span class="hl-brackets">(</span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">))</span></pre></div></div>
<p>If we want the sum of all of the bytes:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-builtin">sum</span><span class="hl-brackets">(</span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">))</span></pre></div></div>
<p>While very useful, iterators do have some downsides to them. The most obvious is that they are only good for one pass over the data. They also generally require you to add extra data members to your class in order to keep track of your current iterator position. Depending on what you are iterating over, this process can become quite complex.  Iterators also only allow you to perform one &#8220;type&#8221; of iteration, i.e., in one direction or over one piece of internal data.  You might address this by adding flags to your class but this will further clutter the class and decrease readability. So how can you simply add multiple types of iteration to a class? Enter the generator! </p>
<h2><a name="Generators">Generators</a></h2>
<p>A generator is a function that creates, or generates, an iterator. In order for a function to become a generator it must return a value using the <code>yield</code> keyword.</p>
<p>Generators are interesting because they are functions, yet execution does not run through them as it does in a normal function. The first time execution enters a generator function it will start at the beginning of the function and continue until the <code>yield</code> keyword is encountered. When the iteration continues, execution will continue in the generator function on the statement immediately following the <code>yield</code> keyword. All local variables in the function will remain intact. If the yield statement occurs within a loop, execution will continue within the loop as though execution had not been interrupted.</p>
<p>Continuing with the ByteValue example, let&#8217;s add a generator function named <code>reverse</code> that can be used to iterate through the byte vales of the string in reverse order:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">reverse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">)
	</span><span class="hl-identifier">while </span><span class="hl-brackets">(</span><span class="hl-identifier">current_item</span><span class="hl-code"> &gt; </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">current_item</span><span class="hl-default"> -= </span><span class="hl-number">1
		</span><span class="hl-reserved">yield </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])</span></pre></div></div>
<p>So what&#8217;s going on here?  The first thing to notice is that we did not add anymore data members to our class, this generator is a self-contained unit. Secondly, since this is a generator, our counter <code>current_item</code> can be a local variable.</p>
<p>In the <code>reverse</code> function the first step is to initialize <code>current_item</code>, which represents the current character in the string, to be equal to the length our string. We initialize it to the length of the string instead of zero since we are iterating through the string in reverse.  Next we have a while loop that loops while <code>current_item</code> is greater than zero. We then subtract one from our counter, to give us the current character to process. Finally, we yield the byte value of the current character.</p>
<p><strong>Note:</strong> We subtract one from our counter the first time through the loop because Python is zero-based and the length of a list minus one gives us the position of the last item in the list. In our examples we have used the following string:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">abcdef
</span><span class="hl-number">012345</span></pre></div></div>
<p>When we calculate the length of the string we get 6. We then subtract 1 from that number, leaving 5, which is the index of the last number in the string.  </p>
<p>Making use of our new generator function, we run the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">for </span><span class="hl-identifier">byte </span><span class="hl-reserved">in </span><span class="hl-identifier">bv</span><span class="hl-default">.</span><span class="hl-identifier">reverse</span><span class="hl-brackets">()</span><span class="hl-default">:
	</span><span class="hl-reserved">print </span><span class="hl-identifier">byte</span></pre></div></div>
<p>We get our favourite byte values in reverse:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-number">102
101
100
99
98
97</span></pre></div></div>
<h2><a name="LookingCloselyAtTheGenerator">Looking closely at the Generator</a></h2>
<p>Let&#8217;s take a detailed look at what is happening in the generator in the same way that we did earlier with the iterator object. The first thing that happens when you call a generator function is NOT the execution of the actual function, rather, it is the creation of a generator object. Running the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">gen</span><span class="hl-default"> = </span><span class="hl-identifier">bv</span><span class="hl-default">.</span><span class="hl-identifier">reverse</span><span class="hl-brackets">()
</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span></pre></div></div>
<p>will result in:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-default">&lt;</span><span class="hl-identifier">generator object at </span><span class="hl-number">0</span><span class="hl-identifier">xb7d8e04c</span><span class="hl-default">&gt;</span></pre></div></div>
<p>This demonstrates that, as stated above, the first call to our generator function does not return the byte value of that last character in the string, instead it creates a generator object. In fact the first time a generator function is called, the actual function is not executed at all. A generator object is &#8220;what Python uses to implement generator iterators. They are normally created by iterating over a function that yields values&#8221;.<a href="#3">[3]</a></p>
<p>Once we have a generator object we can start calling its <code>next</code> function (sound familiar?) to perform the action iteration. An example of this can be found in Listing 5. The results of this execution can be found in Listing 6. The results will seem very familiar to you, especially the <code>StopIteration</code> exception.</p>
<p><strong>Listing 5</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python

</span><span class="hl-reserved">class </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">data</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default"> = </span><span class="hl-identifier">data
		self</span><span class="hl-default">.</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-number">0
	</span><span class="hl-reserved">def </span><span class="hl-identifier">__iter__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-reserved">return </span><span class="hl-identifier">self

	</span><span class="hl-reserved">def </span><span class="hl-identifier">next</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">current_item</span><span class="hl-code"> == </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-reserved">raise StopIteration
		else</span><span class="hl-default">:
			</span><span class="hl-identifier">byte_value</span><span class="hl-default"> = </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">current_item</span><span class="hl-default"> += </span><span class="hl-number">1
			</span><span class="hl-reserved">return </span><span class="hl-identifier">byte_value
		</span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data

	</span><span class="hl-reserved">def </span><span class="hl-identifier">reverse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">)
		</span><span class="hl-identifier">while </span><span class="hl-brackets">(</span><span class="hl-identifier">current_item</span><span class="hl-code"> &gt; </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-identifier">current_item</span><span class="hl-default"> -= </span><span class="hl-number">1
			</span><span class="hl-reserved">yield </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])

</span><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:

	</span><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">gen</span><span class="hl-default"> = </span><span class="hl-identifier">bv</span><span class="hl-default">.</span><span class="hl-identifier">reverse</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
	</span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
	</span><span class="hl-comment"># Someone is launching this directly
	</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p><strong>Listing 6</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-number">102
101
100
99
98
97
</span><span class="hl-identifier">Traceback </span><span class="hl-brackets">(</span><span class="hl-identifier">most recent call last</span><span class="hl-brackets">)</span><span class="hl-default">:
  </span><span class="hl-identifier">File </span><span class="hl-quotes">&quot;</span><span class="hl-string">Listing5.py</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-identifier">line </span><span class="hl-number">40</span><span class="hl-default">, </span><span class="hl-reserved">in</span><span class="hl-default"> ?
    </span><span class="hl-identifier">main</span><span class="hl-brackets">()
  </span><span class="hl-identifier">File </span><span class="hl-quotes">&quot;</span><span class="hl-string">Listing5.py</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-identifier">line </span><span class="hl-number">36</span><span class="hl-default">, </span><span class="hl-reserved">in </span><span class="hl-identifier">main
    </span><span class="hl-reserved">print </span><span class="hl-identifier">gen</span><span class="hl-default">.</span><span class="hl-identifier">next</span><span class="hl-brackets">()
</span><span class="hl-reserved">StopIteration</span></pre></div></div>
<p>If we want to look at the contents of the generator object we could use the following code:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">print </span><span class="hl-builtin">dir</span><span class="hl-brackets">(</span><span class="hl-identifier">gen</span><span class="hl-brackets">)</span></pre></div></div>
<p>And getting the following results:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">__class__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__delattr__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__doc__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__getattribute__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__hash__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__init__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__iter__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__new__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__reduce__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__reduce_ex__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__repr__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__setattr__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">__str__</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">gi_frame</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">gi_running</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">next</span><span class="hl-quotes">'</span><span class="hl-brackets">]</span></pre></div></div>
<p>Notice that the generator object contains the <code>__iter__</code> and <code>next</code> functions making the generator object itself an iterator. Because the generator itself is an iterator object, the same built-in iterator functions I mentioned earlier can also be used on our generators:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">print </span><span class="hl-builtin">sum</span><span class="hl-brackets">(</span><span class="hl-identifier">bv</span><span class="hl-code">.</span><span class="hl-identifier">reverse</span><span class="hl-brackets">())</span></pre></div></div>
<p>It is also important to remember that your generator or iterator does not have to perform only &#8220;dumb&#8221; iteratation, simply moving through some sort of an internal list. Rather, it can make decisions just like any other block of code.</p>
<p>For example, letÃ¢Â€Â™s say that in our <code>reverse</code> generator we want to use the byte value 99 as an end condition. We can do something similar to the example found in Listing 7.</p>
<p><strong>Listing 7</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">reverse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">)
	</span><span class="hl-identifier">while </span><span class="hl-brackets">(</span><span class="hl-identifier">current_item</span><span class="hl-code"> &gt; </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">current_item</span><span class="hl-default"> -= </span><span class="hl-number">1
		</span><span class="hl-identifier">value</span><span class="hl-default"> = </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">value</span><span class="hl-code"> == </span><span class="hl-number">99</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-reserved">return
		yield </span><span class="hl-identifier">value</span></pre></div></div>
<p>In Listing 7 if the byte value equals 99 we return from our generator function using the <code>return</code> keyword. Since we didn&#8217;t yield anything this will cause the <code>StopIteration</code> exception to be fired halting the iteration.</p>
<p>Be careful about getting too smart with your iteration because you cannot return any information from a generator you can only yield it. So if you tried to execute the code in Listing 8, in an attempt to return one last value before quitting (or if you wanted to return a success or failure code) you will get the following error when the <code>return value</code> line of code is executed:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">SyntaxError</span><span class="hl-default">: </span><span class="hl-quotes">'</span><span class="hl-string">return</span><span class="hl-quotes">' </span><span class="hl-identifier">with argument inside generator</span></pre></div></div>
<p><strong>Listing 8</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">reverse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">)
	</span><span class="hl-identifier">while </span><span class="hl-brackets">(</span><span class="hl-identifier">current_item</span><span class="hl-code"> &gt; </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">current_item</span><span class="hl-default"> -= </span><span class="hl-number">1
		</span><span class="hl-identifier">value</span><span class="hl-default"> = </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">value</span><span class="hl-code"> == </span><span class="hl-number">99</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-reserved">return </span><span class="hl-identifier">value
		</span><span class="hl-reserved">yield </span><span class="hl-identifier">value</span></pre></div></div>
<h2><a name="ButWhatAboutIterables">But what about iterables?</a></h2>
<p>I&#8217;m sure that by now you are wondering about the iterable objects that I mentioned at the start of this tutorial. As you have probably guessed, simply making your class an iterator isn&#8217;t that useful unless it is only performing one task like our ByteValue example. Since your classes will generally be performing more than one task, you will likely want to make your class an iterable object rather than an iterator object. To recap, iterable objects return an iterator object when their <code>__iter__</code> function is called, which allows for multiple passes over their data.</p>
<h2><a name="CreatingAnIterableObject">Creating an Iterable object</a></h2>
<p>Since the definition of an iterable object is an object that returns an iterator object when its <code>__iter__</code> function is called, creating an iterable object can be done in a variety of ways. Two options that come to mind are: 1)creating an iterator helper class to perform the iteration and, 2) using a generator function. I prefer using a generator function since it keeps the functionality within the main class.</p>
<p>See Listing 9 for an example of creating an iterarable object using a generator. You will see that we have replaced the <code>next</code> function with the <code>forward</code> function. The <code>forward</code> function is a generator that iterates through the data in the &#8220;forward&#8221; direction. In the <code>__iter__</code> function we return the <strong>results</strong> of a call to the <code>forward</code> function, a generator object. Since generator objects contain the iterator protocol and are, in fact iterators, by returning one from our <code>__init__</code> function we have successfully created an iterable.</p>
<p><strong>Listing 9</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-identifier">object</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">data</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">data</span><span class="hl-default"> = </span><span class="hl-identifier">data

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__iter__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#We are an iterable, so return our iterator
		</span><span class="hl-reserved">return </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">forward</span><span class="hl-brackets">()

	</span><span class="hl-reserved">def </span><span class="hl-identifier">forward</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#The forward generator
		</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-number">0
		</span><span class="hl-identifier">while </span><span class="hl-brackets">(</span><span class="hl-identifier">current_item</span><span class="hl-code"> &lt; </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-identifier">byte_value</span><span class="hl-default"> = </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])
			</span><span class="hl-identifier">current_item</span><span class="hl-default"> += </span><span class="hl-number">1
			</span><span class="hl-reserved">yield </span><span class="hl-identifier">byte_value

	</span><span class="hl-reserved">def </span><span class="hl-identifier">reverse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#The reverse generator
		</span><span class="hl-identifier">current_item</span><span class="hl-default"> = </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">)
		</span><span class="hl-identifier">while </span><span class="hl-brackets">(</span><span class="hl-identifier">current_item</span><span class="hl-code"> &gt; </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-identifier">current_item</span><span class="hl-default"> -= </span><span class="hl-number">1
			</span><span class="hl-reserved">yield </span><span class="hl-builtin">ord</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">data</span><span class="hl-brackets">[</span><span class="hl-identifier">current_item</span><span class="hl-brackets">])

</span><span class="hl-reserved">def </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span><span class="hl-default">:
    </span><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abc</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
    </span><span class="hl-reserved">for </span><span class="hl-identifier">v </span><span class="hl-reserved">in </span><span class="hl-identifier">bv</span><span class="hl-default">:
        </span><span class="hl-reserved">if </span><span class="hl-identifier">v </span><span class="hl-reserved">in </span><span class="hl-identifier">bv</span><span class="hl-default">:
            </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">We have a %d</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-identifier">v

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
    </span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>Now that we have an iterable object, we can iterate over it as many times as we want. We can even have fun with nested iteration:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">bv</span><span class="hl-default"> = </span><span class="hl-identifier">ByteValue</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">abcdef</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">for </span><span class="hl-identifier">value </span><span class="hl-reserved">in </span><span class="hl-identifier">bv</span><span class="hl-default">:
	</span><span class="hl-reserved">print </span><span class="hl-identifier">value
	</span><span class="hl-reserved">for </span><span class="hl-identifier">second_value </span><span class="hl-reserved">in </span><span class="hl-identifier">bv</span><span class="hl-default">:
		</span><span class="hl-reserved">print </span><span class="hl-identifier">second_value</span></pre></div></div>
<h2><a name="Conclusion">Conclusion</a></h2>
<p>This concludes our introduction to iterators, iterables, and generators. I hope I have demonstrated the immense power and flexibility that they provide. In general, making your object an iterable object and/or using generators allows for more flexibility than simple iterator objects provide. For most complex classes or complex sets of data, multiple iterations are a given.</p>
<p>With all of the praise that I have heaped upon iterators, iterables, and generators, it&#8217;s important to remember that they are not a panacea and should not be used in every case where a sequence of items is needed. There are many instances where a returning a list is the desired result. This being said, iterators, iterables, and generators are extremely useful and provide a great way to loop through data.</p>
<p><a name="1">[1]</a> <a href="http://docs.python.org/tut/node18.html">http://docs.python.org/tut/node18.html</a><br />
<a name="2">[2]</a> <a href="http://docs.python.org/lib/typeiter.html">http://docs.python.org/lib/typeiter.html</a><br />
<a name="3">[3]</a> <a href="http://docs.python.org/api/gen-objects.html">http://docs.python.org/api/gen-objects.html</a></generator></p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2009/02/23/iterators-iterables-and-generators-oh-my/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>DodgerEditor 0.1a</title>
		<link>http://www.learningpython.com/2008/11/14/dodgereditor-01a/</link>
		<comments>http://www.learningpython.com/2008/11/14/dodgereditor-01a/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 23:24:20 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[dodger]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Dodger]]></category>
		<category><![CDATA[game engine]]></category>
		<category><![CDATA[level editor]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=103</guid>
		<description><![CDATA[So just to prove that I&#8217;m a masochist and that the Dodger Editor is not dead (even though I don&#8217;t think that anyone has been using it) I thought I&#8217;d post a quick update. No the editor is not dead and no neither am I. I&#8217;m still writing for Python Magazine and working on the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2008%2F11%2F14%2Fdodgereditor-01a%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2008%2F11%2F14%2Fdodgereditor-01a%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>So just to prove that I&#8217;m a masochist and that the Dodger Editor is not dead (even though I don&#8217;t think that anyone has been using it) I thought I&#8217;d post a quick update. No the editor is not dead and no neither am I.</p>
<p>I&#8217;m still writing for Python Magazine and working on the editor in some of the free time that I get. I just added a selection cursor mode to the editor which makes it easier for me to use. You can see it in the second row of the pallet in the following screen shot.</p>
<div id="attachment_104" class="wp-caption alignnone" style="width: 310px"><a href="http://www.learningpython.com/wp-content/uploads/2008/11/editor_06.png"><img src="http://www.learningpython.com/wp-content/uploads/2008/11/editor_06-300x214.png" alt="Now with a Select Mode!" title="editor_06" width="300" height="214" class="size-medium wp-image-104" /></a><p class="wp-caption-text">Now with a Select Mode!</p></div>
<p>If you want access to the newest code you can grab it from the mercurial repository: <a href="http://freehg.org/u/selsine/dodger/">http://freehg.org/u/selsine/dodger/</a></p>
<p>If anyone is at all interested in this project, whether it&#8217;s using or helping to develop, or just some suggestions please let me know. I&#8217;m always open to opinions. If I get the time I&#8217;d like to work on a short post showing you how you can use the Dodger Editor to create the level files for a game, when that will be I don&#8217;t know but hopefully soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2008/11/14/dodgereditor-01a/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

