<?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/"
	>

<channel>
	<title>learning python</title>
	<atom:link href="http://www.learningpython.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.learningpython.com</link>
	<description>one man's journey into python...</description>
	<pubDate>Tue, 10 Mar 2009 21:54:54 +0000</pubDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<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 Magazine]]></category>

		<category><![CDATA[python]]></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 concepts of [...]]]></description>
			<content:encoded><![CDATA[<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 (&#8217;a') 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>
		</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 editor [...]]]></description>
			<content:encoded><![CDATA[<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>
		</item>
		<item>
		<title>TextWidget 0.1</title>
		<link>http://www.learningpython.com/2008/09/21/textwidget-01/</link>
		<comments>http://www.learningpython.com/2008/09/21/textwidget-01/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 21:41:50 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
		
		<category><![CDATA[TextWidget]]></category>

		<category><![CDATA[pygame]]></category>

		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=99</guid>
		<description><![CDATA[It&#8217;s been a long time since I worked on TextWidget at all, but since someone posted a question about it I decided to fix the issue and re-release the source. But since I didn&#8217;t want to simply update the blog post I decided to give the project a proper home on google code: http://code.google.com/p/textwidget/
The project [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a long time since I worked on <a href="http://www.learningpython.com/2006/12/13/textwidget-a-simple-text-class-for-pygame/">TextWidget</a> at all, but since someone posted a question about it I decided to fix the issue and re-release the source. But since I didn&#8217;t want to simply update the blog post I decided to give the project a proper home on google code: <a href="http://code.google.com/p/textwidget/">http://code.google.com/p/textwidget/</a></p>
<p>The project is really simple and meant as an easy way for you to create &#8220;text buttons&#8221; for your PyGame projects.  It&#8217;s not meant to be the definitive way to do this, just a simple solution for people that just want to drop a class in and have working &#8220;text buttons&#8221;. It&#8217;s LGPL so you can use it in whatever way you want. If you do decide to use it please drop me an email and let me know.</p>
<p>For more information on how to use the project please take a look at the initial <a href="http://www.learningpython.com/2006/12/13/textwidget-a-simple-text-class-for-pygame/">blog post</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2008/09/21/textwidget-01/feed/</wfw:commentRss>
		</item>
		<item>
		<title>An Introduction to PyQt: creating GUIs with Python&#8217;s QT bindings</title>
		<link>http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/</link>
		<comments>http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/#comments</comments>
		<pubDate>Sat, 20 Sep 2008 19:21:46 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
		
		<category><![CDATA[PyQt]]></category>

		<category><![CDATA[python]]></category>

		<category><![CDATA[gui]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=88</guid>
		<description><![CDATA[By: Mark Mruss
Note: This article was first published the December 2007 issue of Python Magazine
While the command line will never cease to be useful, nothing will impress your friends more than your latest python masterpiece wrapped up in a slick cross-platform Graphical User Interface (GUI). This tutorial will show you how to create a simple [...]]]></description>
			<content:encoded><![CDATA[<p><strong>By: Mark Mruss</strong></p>
<p><strong>Note:</strong> This article was first published the December 2007 issue of <a href="http://www.pythonmagazine.com">Python Magazine</a></p>
<p>While the command line will never cease to be useful, nothing will impress your friends more than your latest python masterpiece wrapped up in a slick cross-platform Graphical User Interface (GUI). This tutorial will show you how to create a simple GUI in Python using PyQt4.</p>
<ol>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#InstallingPyQt4">Installing PyQt4</a></li>
<li><a href="#FirstApplication">Your First PyQt4 Application</a></li>
<li><a href="#TheMainWindow">The Main Window</a></li>
<li><a href="#AddingSomeWidgets">Adding Some Widgets</a></li>
<li><a href="#SignalHandling">Signal Handling</a></li>
<li><a href="#DisplayingAMessage">Displaying a Message</a></li>
<li><a href="#Conclusion">Conclusion</a></li>
</ol>
<p><span id="more-88"></span></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>While writing console applications and modules using Python can be very enjoyable, I think that almost everyone learning Python eventually wants to do one thing: create a application with a full Graphical User Interface (GUI). Fortunately for Python users, there are a few options available to achieve this. One of the more interesting options is PyQt4, Python bindings for the fourth version of the famous cross platform application development API Qt.</p>
<p>Qt, owned by Trolltech software, is probably most famous as the foundation for the KDE window manager on Linux. PyQt4, and PyQt version 3, were created and are maintained by Riverbank software.  Qt and PyQt4 are both open source and free for open source applications, but if you wish to develop commercial applications you will need to purchase the commercial versions of both Qt and PyQt4.</p>
<p>One of the best features of Qt is that it is a cross platform library which means that it gives you easy access to the three main desktop environments: Linux, Windows, and OS X. This is an important requirement for me because when I&#8217;m developing a small open source application I want it available on as many platforms as possible. The nice thing about Qt’s latest version, Qt4, is that it also gives your GUI a native look and feel on the different operating systems.</p>
<p>This article will create a simple application to introduce you to the basic features of PyQt4. The application will consist of a single window that does the following: accepts user input, responds to a button click, and displays a message using a pop-up dialog.</p>
<h2><a name="InstallingPyQt4">Installing PyQt4</a></h2>
<p>Before installing PyQt4 you need to have Python 2.5 or newer and Qt version 4 installed. You can download Python 2.5 from the main Python website.<a href="#1">[1]</a> Qt version 4 is available from the TrollTech website&#8217;s Downloads section.<a href="#2">[2]</a> Installing PyQt4 on Linux, Windows, or OS X is relatively easy, and I know since I installed it on each of them. You can download the different PyQt4 packages from the Riverbank website, including an all in one (Qt version 4 included) installer for Windows.<a href="#3">[3]</a> There are also installation instructions in the PyQt4 online documentation that are worth a read if you are new to installing software from source.<a href="#4">[4]</a> If you are using a modern Linux distribution, you may want to consider using your package manager to install PyQt4 as it should being along all the necessary dependencies for you.</p>
<h2><a name="FirstApplication">Your First PyQt4 Application</a></h2>
<p>Now that you have PyQT4 properly installed, let’s dive right in and create an application. The first step is to start a new Python file, I called mine <code>PyQt4Intro.py</code> but you can call it whatever you like. Set it up using the following code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python
</span><span class="hl-reserved">import </span><span class="hl-identifier">PyQt4

</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-reserved">pass</span></pre></div></div>
<p>If you&#8217;ve read any of my other columns, you may recognize this code as a general template that I use for my Python projects. The major difference in this example is that we import PyQt4. After you have set your file up run the code. If all goes well nothing will happen. If you do get an error, something like the following, it probably means that PyQt4 is not installed properly:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>ImportError: No module named PyQt4</pre></div></div>
<p>Remember that PyQT4 requires Python 2.5. If you have Python 2.5 and older versions of Python installed, try specifying <code>python2.5</code> when you run the script:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>python2.5 PyQt4Intro.py</pre></div></div>
<p>Now that we have everything in order, let&#8217;s create and show a window. After all this is a GUI tutorial! If you are creating a GUI application using PyQt4 (of course, you can also create a non-GUI application using PyQt4), you will need to create a <code>QApplication</code> instance. </p>
<p>The PyQt4 documentation provides a great description of the &#8220;QApplication&#8221; class: &#8220;The QApplication class manages the GUI application&#8217;s control flow and main settings. It contains the main event loop, where all events from the window system and other sources are processed and dispatched. It also handles the application&#8217;s initialization and finalization, and provides session management. It also handles most system-wide and application-wide settings. For any GUI application that uses Qt, there is precisely one QApplication object, no matter whether the application has 0, 1, 2 or more windows at any time.&#8221;<a href="#5">[5]</a></p>
<p>What we need to do is create the one and only <code>QApplication</code> instance for our application. To do this, we will import two new modules:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtGui</span></pre></div></div>
<p>The first line imports the <code>sys</code> module. This is needed to initialize the <code>QApplication</code>. The second line imports the <code>QtGui</code> module. It allows us to reference <code>QApplication</code> and other <code>QtGui</code> components. </p>
<p>In our main block, we will add the following code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><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
	# Create the QApplication
	</span><span class="hl-identifier">app</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QApplication</span><span class="hl-brackets">(</span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">)
	</span><span class="hl-comment"># Enter the main loop
	</span><span class="hl-identifier">app</span><span class="hl-default">.</span><span class="hl-identifier">exec_</span><span class="hl-brackets">()</span></pre></div></div>
<p>This will create the <code>QApplication</code> instance, initialized with the command-line parameters that may be passed to our script. This is a necessary parameter to the <code>QApplication</code> class and is the reason that we imported the <code>sys</code> module.  The next call is to the <code>exec</code> function which &#8220;enters the main event loop and waits until exit() is called or the main widget is destroyed&#8221;.<a href="#6">[6] </a></p>
<p>If you run the entire script at this point, which I don&#8217;t necessarily recommend since it will seem to hang, you will be running a PyQt4 application. You won&#8217;t see anything since there is no visible component. However, the script will continue to run in its main loop instead of returning right after being executed. If you do decide to run this script, use CTRL+Z to exit.</p>
<h2><a name="TheMainWindow">The Main Window</a></h2>
<p>GUI applications without a visible component are not that useful so let&#8217;s add a window to our application. We will do this by sub-classing the <code>QMainWindow</code> class. The <code>QMainWindow</code> class &#8220;provides a framework for building an application&#8217;s user interface. Qt has &#8220;QMainWindow&#8221; and its related classes for main window management. &#8220;QMainWindow&#8221; has its own layout to which you can add &#8220;QToolBars&#8221;, &#8220;QDockWindows&#8221;, a &#8220;QMenuBar&#8221;, and a &#8220;QStatusBar&#8221;.&#8221;<a href="#7">[7]</a></p>
<p><strong>Note:</strong> There are other ways to create a visible window. For example you could use a <code>QWidget</code> to accomplish much of what we are going to do. I chose to use the <code>QMainWindow</code> since it provides an application framework that you might want to use when building a full GUI application.</p>
<p>We can subclass the <code>QMainWindow</code> as follows:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">(</span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMainWindow</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">win_parent</span><span class="hl-code"> = </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#Init the base class
		</span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMainWindow</span><span class="hl-default">.</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">win_parent</span><span class="hl-brackets">)</span></pre></div></div>
<p>Then in the main block we can create and show our main window like this:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">app</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QApplication</span><span class="hl-brackets">(</span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">)
</span><span class="hl-comment">#The Main window
</span><span class="hl-identifier">main_window</span><span class="hl-default"> = </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">()
</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">show</span><span class="hl-brackets">()
</span><span class="hl-comment"># Enter the main loop
</span><span class="hl-identifier">app</span><span class="hl-default">.</span><span class="hl-identifier">exec_</span><span class="hl-brackets">()</span></pre></div></div>
<p>The entire source code thus far is found in Listing 1. When you run the code, you will finally be greeted with your very first PyQt4 window. It will look something similar to Figure 1.</p>
<p><strong>Listing 1</strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python
</span><span class="hl-reserved">import </span><span class="hl-identifier">PyQt4
</span><span class="hl-reserved">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtGui

</span><span class="hl-reserved">class </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">(</span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMainWindow</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">win_parent</span><span class="hl-code"> = </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#Init the base class
		</span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMainWindow</span><span class="hl-default">.</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">win_parent</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
	# Create the QApplication
	</span><span class="hl-identifier">app</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QApplication</span><span class="hl-brackets">(</span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">)
	</span><span class="hl-comment">#The Main window
	</span><span class="hl-identifier">main_window</span><span class="hl-default"> = </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">()
	</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">show</span><span class="hl-brackets">()
	</span><span class="hl-comment"># Enter the main loop
	</span><span class="hl-identifier">app</span><span class="hl-default">.</span><span class="hl-identifier">exec_</span><span class="hl-brackets">()</span></pre></div></div>
<div id="attachment_91" class="wp-caption alignnone" style="width: 216px"><a href="http://www.learningpython.com/wp-content/uploads/2008/09/figure1.png"><img src="http://www.learningpython.com/wp-content/uploads/2008/09/figure1.png" alt="Figure 1" title="Figure 1" width="206" height="128" class="size-medium wp-image-91" /></a><p class="wp-caption-text">Figure 1</p></div>
<h2><a name="AddingSomeWidgets">Adding Some Widgets</a></h2>
<p>A blank window is only slightly more useful then an invisible oen. Therefore our next step is to add some functionality to our window by adding some interactive widgets. In order to do this, we will set the central widget of our main window and use a &#8220;geometry manager&#8221; (or &#8220;layout manager&#8221;) class to manage the positioning of our widgets.</p>
<p>We will add a new function to our <code>HelloWindow</code> class called <code>create_widgets</code> where we will create all of our widgets. We will call this function from the <code>__init__</code> function. The first step in the <code>create_widgets</code> function is to create a widget that will serve as the &#8220;central widget&#8221; for our main window. As mentioned earlier, the <code>QMainWindow</code> class already has a built-in layout making it easy to add menus, toolbars, and other items common to applications. <code>QMainWindow</code> classes also have a &#8220;central widget&#8221; which you can think of as the main part of the application. More to the point, the &#8220;central widget&#8221; is not the toolbars, menu, or docking panes, but the actual functional area of the application. For a greater description of the &#8220;central widget&#8221; see the PyQt4 website.<a href="#8">[8]</a></p>
<p>We will create and set our &#8220;central widget&#8221; using the following code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">create_widgets</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">central_widget</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QWidget</span><span class="hl-brackets">()
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">setCentralWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">central_widget</span><span class="hl-brackets">)</span></pre></div></div>
<p>So far this won&#8217;t do anything, since we still have not added anything interactive. To add interactivity, we must add widgets to our &#8220;central widget&#8221;. Rather than place the widgets in static positions, we will use a layout manager to automatically position and adjust our widgets. If you are at all familiar with modern GUI toolkits, the idea of a layout manager should be familiar to you. They serve as a way to &#8220;pack&#8221; widgets into an area where their positions will be relative to each other and to the window. When you resize the window (or area), geometry manager&#8217;s will automatically adjust the size and positions of their child widgets to accommodate the new size.</p>
<p>We will be creating three widgets in our simple application: </p>
<p>1. A <code>QLabel</code> widget to display some static text.<br />
2. A <code>QLineEdit</code> widget to let the user enter some text into an edit field.<br />
3. A <code>QPushButton</code> button widget that will pop up a dialog to display a message when the user clicks on it.</p>
<p>We will create the widgets using the following code. Notice that in the creation of the <code>QLabel</code> and <code>QPushButton</code> widgets we are also setting the text that will appear on each widget. (We can do the same for the <code>QLineEdit</code>, but for now we&#8217;ll leave it blank):</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">create_widgets</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">#Widgets
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">label</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLabel</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Say hello:</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_edit</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLineEdit</span><span class="hl-brackets">()
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_button</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QPushButton</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Push Me!</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>Next, we will create a <code>QHBoxLayout</code> instance to serve as the central widget&#8217;s layout manager. The <code>QHBoxLayout</code> class is a specific type of layout manager that lays widgets out, and manage their positions, in the horizontal direction. Once we have created the <code>QHBoxLayout</code> instance, we will add our three widgets to it. Adding widgets to a <code>QHBoxLayout</code> will pack them from left to right:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Horizontal layout
</span><span class="hl-identifier">h_box</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QHBoxLayout</span><span class="hl-brackets">()
</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">label</span><span class="hl-brackets">)
</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_edit</span><span class="hl-brackets">)
</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-brackets">)</span></pre></div></div>
<p>The last step in our widget creation is to set <code>h_box</code> as the layout manager for our central widget:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Create central widget, add layout, and set
</span><span class="hl-identifier">central_widget</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QWidget</span><span class="hl-brackets">()
</span><span class="hl-identifier">central_widget</span><span class="hl-default">.</span><span class="hl-identifier">setLayout</span><span class="hl-brackets">(</span><span class="hl-identifier">h_box</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">setCentralWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">central_widget</span><span class="hl-brackets">)</span></pre></div></div>
<p>The entire code can be seen in Listing 2. When you run this code, you will finally be greeted with a window containing actual widgets. This is illustrated in Figure 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-reserved">import </span><span class="hl-identifier">PyQt4
</span><span class="hl-reserved">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtGui

</span><span class="hl-reserved">class </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">(</span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMainWindow</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">win_parent</span><span class="hl-code"> = </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#Init the base class
		</span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMainWindow</span><span class="hl-default">.</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">win_parent</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">create_widgets</span><span class="hl-brackets">()

	</span><span class="hl-reserved">def </span><span class="hl-identifier">create_widgets</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">#Widgets
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">label</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLabel</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Say hello:</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_edit</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLineEdit</span><span class="hl-brackets">()
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_button</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QPushButton</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Push Me!</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-comment">#Horizontal layout
		</span><span class="hl-identifier">h_box</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QHBoxLayout</span><span class="hl-brackets">()
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">label</span><span class="hl-brackets">)
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_edit</span><span class="hl-brackets">)
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-brackets">)
		</span><span class="hl-comment">#Create central widget, add layout and set
		</span><span class="hl-identifier">central_widget</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QWidget</span><span class="hl-brackets">()
		</span><span class="hl-identifier">central_widget</span><span class="hl-default">.</span><span class="hl-identifier">setLayout</span><span class="hl-brackets">(</span><span class="hl-identifier">h_box</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">setCentralWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">central_widget</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
	# Create the QApplication
	</span><span class="hl-identifier">app</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QApplication</span><span class="hl-brackets">(</span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">)
	</span><span class="hl-comment">#The Main window
	</span><span class="hl-identifier">main_window</span><span class="hl-default"> = </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">()
	</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">show</span><span class="hl-brackets">()
	</span><span class="hl-comment"># Enter the main loop
	</span><span class="hl-identifier">app</span><span class="hl-default">.</span><span class="hl-identifier">exec_</span><span class="hl-brackets">()</span></pre></div></div>
<div id="attachment_92" class="wp-caption alignnone" style="width: 296px"><a href="http://www.learningpython.com/wp-content/uploads/2008/09/figure2.png"><img src="http://www.learningpython.com/wp-content/uploads/2008/09/figure2.png" alt="Figure 2" title="Figure 2" width="286" height="128" class="size-medium wp-image-92" /></a><p class="wp-caption-text">Figure 2</p></div>
<h2><a name="SignalHandling">Signal Handling</a></h2>
<p>Responding to the user’s interaction with the GUI is something that must be done in all GUI applications. Therefore the next step in constructing a GUI application is signal or event handling. If you are unfamiliar with these terms you can thing of it his way: when the end user interacts with your GUI, her interaction will causes signals to be sent to your application. So if she clicks on a button the clicked() signal will be sent. If your application wants to do something when that button is clicked, then you will have to handle that widgets <code>clicked()</code> signal.  In our example, we are going to show a pop up a dialog when the user clicks on our button widget.</p>
<p>I find connecting to signals in PyQt4 a bit odd because of a built in macro that needs to be called but the process is relatively easy so I shouldn&#8217;t complain too much. The idea is similar to that of other Python GUI toolkits: you connect functions that you have written to signals or events that are emitted by a widget. So whenever a widget emits a signal that has been connected to a function, that function will be called.</p>
<p><strong>Note:</strong> Qt goes a bit further with the idea of built-in &#8220;slots&#8221; but for the sake of this tutorial we will be ignoring them. For more information on &#8220;slots&#8221; please see the PyQt4 documentation.</p>
<p>In order for the &#8220;QPushButton&#8221; to do something when pushed, we have to connect a function in our <code>HelloWindow</code> class with the <code>clicked</code> signal.  To do this, we need to call the <code>QObject</code> classes <code>connect</code> static function. We must tell it three things: </p>
<p>1. The <code>QWidget</code> that will emit the signal.<br />
2. The signal that we want to connect to.<br />
3. The function that should be called when the <code>QWidget</code> emits the signal.</p>
<p>In our example, we will do this like so:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#connect signal
</span><span class="hl-identifier">QtCore</span><span class="hl-default">.</span><span class="hl-identifier">QObject</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-code">
	, </span><span class="hl-identifier">QtCore</span><span class="hl-code">.</span><span class="hl-identifier">SIGNAL</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">clicked()</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">
	, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">on_hello_clicked</span><span class="hl-brackets">)</span></pre></div></div>
<p><strong>Note:</strong> We could just as easily have called <code>self.connect</code> since a <code>QMainWindow</code> is a descendant of the <code>QObject</code> class.</p>
<p><code>QtCore.SIGNAL</code> is a macro that you have to use for the second parameter. It accepts the signal name as a string (in this case <code>clicked()</code>) and converts it into an object that is required for the signal connection. The documentation is a bit sparse regarding exactly what the macro does, but luckily for us we don&#8217;t really need to know the details.</p>
<p>In order for this code to compile, we also have to import the <code>QtCore</code> module:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtCore</span></pre></div></div>
<p>We also have to add a new function to the <code>HelloWindow</code> class. This is the function <code>on_hello_clicked</code> that will respond to the <code>clicked()</code> signal:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_hello_clicked</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">Clicked</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>When you run the code in Listing 3, you will see &#8220;Clicked&#8221; printed out to the command line every time you click the &#8220;Push Me!&#8221; button.</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-reserved">import </span><span class="hl-identifier">PyQt4
</span><span class="hl-reserved">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtGui
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtCore

</span><span class="hl-reserved">class </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">(</span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMainWindow</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">win_parent</span><span class="hl-code"> = </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#Init the base class
		</span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMainWindow</span><span class="hl-default">.</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">win_parent</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">create_widgets</span><span class="hl-brackets">()


	</span><span class="hl-reserved">def </span><span class="hl-identifier">create_widgets</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">#Widgets
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">label</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLabel</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Say hello:</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_edit</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLineEdit</span><span class="hl-brackets">()
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_button</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QPushButton</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Push Me!</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

		</span><span class="hl-comment">#connect signal
		</span><span class="hl-identifier">QtCore</span><span class="hl-default">.</span><span class="hl-identifier">QObject</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-code">
			, </span><span class="hl-identifier">QtCore</span><span class="hl-code">.</span><span class="hl-identifier">SIGNAL</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">clicked()</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">
			, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">on_hello_clicked</span><span class="hl-brackets">)


		</span><span class="hl-comment">#Horizontal layout
		</span><span class="hl-identifier">h_box</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QHBoxLayout</span><span class="hl-brackets">()
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">label</span><span class="hl-brackets">)
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_edit</span><span class="hl-brackets">)
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-brackets">)
		</span><span class="hl-comment">#Create central widget, add layout and set
		</span><span class="hl-identifier">central_widget</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QWidget</span><span class="hl-brackets">()
		</span><span class="hl-identifier">central_widget</span><span class="hl-default">.</span><span class="hl-identifier">setLayout</span><span class="hl-brackets">(</span><span class="hl-identifier">h_box</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">setCentralWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">central_widget</span><span class="hl-brackets">)

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_hello_clicked</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">Clicked</span><span class="hl-quotes">&quot;
		
</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
	# Create the QApplication
	</span><span class="hl-identifier">app</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QApplication</span><span class="hl-brackets">(</span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">)
	</span><span class="hl-comment">#The Main window
	</span><span class="hl-identifier">main_window</span><span class="hl-default"> = </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">()
	</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">show</span><span class="hl-brackets">()
	</span><span class="hl-comment"># Enter the main loop
	</span><span class="hl-identifier">app</span><span class="hl-default">.</span><span class="hl-identifier">exec_</span><span class="hl-brackets">()</span></pre></div></div>
<h2><a name="DisplayingAMessage">Displaying a Message</a></h2>
<p>Now that we have a function connected to the clicking of the button widget we need to read the text from the <code>QLineEdit</code> widget and display it to the user. Fortunately both tasks are quite easy in PyQt4. </p>
<p>In order to get the text from a <code>QLineEdit</code> widget, the <code>QLineEdit</code> classes member function <code>displayText</code> needs to be called. The <code>displayText</code> function simply returns the contents of the <code>QLineEdit</code> widget.</p>
<p>Showing a pop-up dialog using PyQt4 is just as easy as getting the contents of a <code>QLineEdit</code> widget, thanks to the <code>QMesssageBox</code> classes static function <code>information</code>.  This function allows you to set the title, text and what buttons are on a simple &#8220;information dialog&#8221;.  Calling it from our PyQt4 application in response to the button click is very simple:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_hello_clicked</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">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMessageBox</span><span class="hl-default">.</span><span class="hl-identifier">information</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">Hello!</span><span class="hl-quotes">&quot;</span><span class="hl-code">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">Hello %s</span><span class="hl-quotes">&quot;</span><span class="hl-code"> % </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_edit</span><span class="hl-code">.</span><span class="hl-identifier">displayText</span><span class="hl-brackets">()</span><span class="hl-code">
		, </span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMessageBox</span><span class="hl-code">.</span><span class="hl-identifier">Ok</span><span class="hl-brackets">)</span></pre></div></div>
<p>In this code, we call the information function, set its title text to be &#8220;Hello!&#8221;, set its main message to be &#8220;Hello &#8221; followed by the contents of the <code>hello_edit</code> <code>QInputEdit</code>, and give it one button, an &#8220;ok&#8221; button. All of the code is found in Listing 4. What this looks like running on Linux, Windows and OS X can be seen in Figure 3, Figure 4, and Figure 5 respectively.</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-reserved">import </span><span class="hl-identifier">PyQt4
</span><span class="hl-reserved">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtGui
</span><span class="hl-reserved">from </span><span class="hl-identifier">PyQt4 </span><span class="hl-reserved">import </span><span class="hl-identifier">QtCore

</span><span class="hl-reserved">class </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">(</span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMainWindow</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">win_parent</span><span class="hl-code"> = </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#Init the base class
		</span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMainWindow</span><span class="hl-default">.</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">win_parent</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">create_widgets</span><span class="hl-brackets">()


	</span><span class="hl-reserved">def </span><span class="hl-identifier">create_widgets</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">#Widgets
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">label</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLabel</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Say hello:</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_edit</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QLineEdit</span><span class="hl-brackets">()
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">hello_button</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QPushButton</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Push Me!</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

		</span><span class="hl-comment">#connect signal
		</span><span class="hl-identifier">QtCore</span><span class="hl-default">.</span><span class="hl-identifier">QObject</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-code">
			, </span><span class="hl-identifier">QtCore</span><span class="hl-code">.</span><span class="hl-identifier">SIGNAL</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">clicked()</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">
			, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">on_hello_clicked</span><span class="hl-brackets">)


		</span><span class="hl-comment">#Horizontal layout
		</span><span class="hl-identifier">h_box</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QHBoxLayout</span><span class="hl-brackets">()
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">label</span><span class="hl-brackets">)
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_edit</span><span class="hl-brackets">)
		</span><span class="hl-identifier">h_box</span><span class="hl-default">.</span><span class="hl-identifier">addWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-brackets">)
		</span><span class="hl-comment">#Create central widget, add layout and set
		</span><span class="hl-identifier">central_widget</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QWidget</span><span class="hl-brackets">()
		</span><span class="hl-identifier">central_widget</span><span class="hl-default">.</span><span class="hl-identifier">setLayout</span><span class="hl-brackets">(</span><span class="hl-identifier">h_box</span><span class="hl-brackets">)
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">setCentralWidget</span><span class="hl-brackets">(</span><span class="hl-identifier">central_widget</span><span class="hl-brackets">)

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_hello_clicked</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">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QMessageBox</span><span class="hl-default">.</span><span class="hl-identifier">information</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">Hello!</span><span class="hl-quotes">&quot;</span><span class="hl-code">
			, </span><span class="hl-quotes">&quot;</span><span class="hl-string">Hello %s</span><span class="hl-quotes">&quot;</span><span class="hl-code"> % </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_edit</span><span class="hl-code">.</span><span class="hl-identifier">displayText</span><span class="hl-brackets">()</span><span class="hl-code">
			, </span><span class="hl-identifier">QtGui</span><span class="hl-code">.</span><span class="hl-identifier">QMessageBox</span><span class="hl-code">.</span><span class="hl-identifier">Ok</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
	# Create the QApplication
	</span><span class="hl-identifier">app</span><span class="hl-default"> = </span><span class="hl-identifier">QtGui</span><span class="hl-default">.</span><span class="hl-identifier">QApplication</span><span class="hl-brackets">(</span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">)
	</span><span class="hl-comment">#The Main window
	</span><span class="hl-identifier">main_window</span><span class="hl-default"> = </span><span class="hl-identifier">HelloWindow</span><span class="hl-brackets">()
	</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">show</span><span class="hl-brackets">()
	</span><span class="hl-comment"># Enter the main loop
	</span><span class="hl-identifier">app</span><span class="hl-default">.</span><span class="hl-identifier">exec_</span><span class="hl-brackets">()</span></pre></div></div>
<div id="attachment_93" class="wp-caption alignnone" style="width: 310px"><a href="http://www.learningpython.com/wp-content/uploads/2008/09/figure3.png"><img src="http://www.learningpython.com/wp-content/uploads/2008/09/figure3-300x217.png" alt="Figure 3" title="Figure 3" width="300" height="217" class="size-medium wp-image-93" /></a><p class="wp-caption-text">Figure 3</p></div>
<div id="attachment_94" class="wp-caption alignnone" style="width: 310px"><a href="http://www.learningpython.com/wp-content/uploads/2008/09/figure4.png"><img src="http://www.learningpython.com/wp-content/uploads/2008/09/figure4-300x220.png" alt="Figure 4" title="Figure 4" width="300" height="220" class="size-medium wp-image-94" /></a><p class="wp-caption-text">Figure 4</p></div>
<div id="attachment_95" class="wp-caption alignnone" style="width: 310px"><a href="http://www.learningpython.com/wp-content/uploads/2008/09/figure5.png"><img src="http://www.learningpython.com/wp-content/uploads/2008/09/figure5-300x230.png" alt="Figure 5" title="Figure 5" width="300" height="230" class="size-medium wp-image-95" /></a><p class="wp-caption-text">Figure 5</p></div>
<h2><a name="Conclusion">Conclusion</a></h2>
<p>That&#8217;s it for this quick introduction to PyQt4. All-in-all, I was pleasantly surprised by PyQt4. Even during my first foray into the toolkit, I found it very straightforward and was able to get things going in a matter of minutes. Granted, what I was trying to accomplish was pretty simple, but it&#8217;s always a good sign when doing something simple is easy!</p>
<p>You should now have enough information to go and create your very own &#8220;GUIfied&#8221; applications. Of course, there is much, much more to PyQt4 than I have covered in this tutorial. But if you use the PyQt4 documentation and the fundamentals from this tutorial, you shouldn&#8217;t have much trouble moving forward.</p>
<p><a name="1">[1]</a> <a href="http://www.python.org/download/">http://www.python.org/download/</a><br />
<a name="2">[2]</a> <a href="http://www.riverbankcomputing.co.uk/pyqt/download.php">http://www.riverbankcomputing.co.uk/pyqt/download.php</a><br />
<a name="3">[3]</a> <a href="http://trolltech.com/downloads">http://trolltech.com/downloads</a><br />
<a name="4">[4]</a> <a href="http://www.riverbankcomputing.com/Docs/PyQt4/pyqt4ref.html#installing-pyqt">http://www.riverbankcomputing.com/Docs/PyQt4/pyqt4ref.html#installing-pyqt</a><br />
<a name="5">[5]</a> <a href="http://www.riverbankcomputing.com/Docs/PyQt4/html/qapplication.html">http://www.riverbankcomputing.com/Docs/PyQt4/html/qapplication.html</a><br />
<a name="6">[6]</a> <a href="http://www.riverbankcomputing.com/Docs/PyQt4/html/qapplication.html#exec">http://www.riverbankcomputing.com/Docs/PyQt4/html/qapplication.html#exec</a><br />
<a name="7">[7]</a> <a href="http://www.riverbankcomputing.com/Docs/PyQt4/html/qmainwindow.html#details">http://www.riverbankcomputing.com/Docs/PyQt4/html/qmainwindow.html#details</a><br />
<a name="8">[8]</a> <a href="http://www.riverbankcomputing.com/Docs/PyQt4/html/qmainwindow.html#details">http://www.riverbankcomputing.com/Docs/PyQt4/html/qmainwindow.html#details</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Dodger Editor 0.1</title>
		<link>http://www.learningpython.com/2008/08/25/dodger-editor-01/</link>
		<comments>http://www.learningpython.com/2008/08/25/dodger-editor-01/#comments</comments>
		<pubDate>Mon, 25 Aug 2008 23:51:50 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
		
		<category><![CDATA[dodger]]></category>

		<category><![CDATA[game engine]]></category>

		<category><![CDATA[python]]></category>

		<category><![CDATA[0.1]]></category>

		<category><![CDATA[Dodger]]></category>

		<category><![CDATA[editor]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=83</guid>
		<description><![CDATA[So here it is the initial release of the Dodger Editor. You can download the source from the google code page. Originally I wanted to wait longer to release the first version, but as time went on and it kept taking longer and longer I realized that if I didn&#8217;t release the first version at [...]]]></description>
			<content:encoded><![CDATA[<p>So here it is the initial release of the Dodger Editor. You can download the source from the <a href="http://code.google.com/p/dodger-editor/">google code page</a>. Originally I wanted to wait longer to release the first version, but as time went on and it kept taking longer and longer I realized that if I didn&#8217;t release the first version at some point in time I might never release it.</p>
<p>If I had gotten done everything that I wanted to get done then I would be releasing the full first version of the project instead of this incredibly alpha release. So if something doesn&#8217;t work don&#8217;t be surprised. That being said you should be able to use it for it&#8217;s basic functionality. Or at least that&#8217;s what I&#8217;m hoping.</p>
<p><strong>Installation</strong></p>
<p>Once you have met the requirements:</p>
<ul>
<li>Python &gt;= 2.5 <a href="http://www.python.org/download/">http://www.python.org/download/</a></li>
<li>GTK+ &gt;= 2.10 <a href="http://www.pygtk.org/downloads.html">http://www.pygtk.org/downloads.html</a></li>
<li>PyGTK &gt;= 2.10 <a href="http://www.pygtk.org/downloads.html">http://www.pygtk.org/downloads.html</a></li>
<li>pyGObject &gt;= 2.10 <a href="http://www.pygtk.org/downloads.html">http://www.pygtk.org/downloads.html</a></li>
<li>pyglet &gt;= 1.1 <a href="http://www.pyglet.org/download.html">http://www.pyglet.org/download.html</a></li>
<li>PyYAML &gt; 3.0 <a href="http://pyyaml.org/wiki/PyYAML">http://pyyaml.org/wiki/PyYAML</a></li>
<li>PyOpenGL 3.x <a href="http://pyopengl.sourceforge.net/">http://pyopengl.sourceforge.net/</a></li>
<li>PyGtkGlExt? <a href="http://www.k-3d.org/gtkglext/Main_Page">http://www.k-3d.org/gtkglext/Main_Page</a></li>
</ul>
<p>You should be able to install dodger by downloading the and extracting the source tarball. Once you have extracted the source change into the source directory and install using:</p>
<p><code><br />
python setyup.py install<br />
</code></p>
<p>If you don&#8217;t want to install and just want to test dodger out simply follow the above instructions except instead of installing dodger run the following:</p>
<p><code><br />
python runner.py<br />
</code></p>
<p><strong>Contributing</strong></p>
<p>I still want to setup a dedicated site that will host a mercurial repository of the code but for now I&#8217;m going to use the fabulous  <a href="http://freehg.org">http://freehg.org</a> site. For now if you want you can pull the source from  <a href="http://freehg.org/u/selsine/dodger/">http://freehg.org/u/selsine/dodger/</a>:</p>
<p><code><br />
hg clone http://freehg.org/u/selsine/dodger/<br />
</code></p>
<p>For now any changes that you make or fixes will have to be emailed as a patch but eventually I want to make it much much easier for people to submit fixes.</p>
<p>If you are really interested in contributing to this project let me know via a comment to this post and or an email. Then once all of the source issue are setup we can start working together.</p>
<p><strong>New Features</strong></p>
<p>Since the last release there has been a lot of changes under the hood. The most visible changes for anyone using dodger is the addition of the zoom feature:</p>
<div id="attachment_84" class="wp-caption alignnone" style="width: 310px"><a href="http://www.learningpython.com/wp-content/uploads/2008/08/dodger_01_01.png"><img class="size-medium wp-image-84" title="dodger_01_01" src="http://www.learningpython.com/wp-content/uploads/2008/08/dodger_01_01-300x211.png" alt="zoom example" width="300" height="211" /></a><p class="wp-caption-text">zoomed out example</p></div>
<div id="attachment_85" class="wp-caption alignnone" style="width: 310px"><a href="http://www.learningpython.com/wp-content/uploads/2008/08/dodger_01_02.png"><img class="size-medium wp-image-85" title="dodger_01_02" src="http://www.learningpython.com/wp-content/uploads/2008/08/dodger_01_02-300x216.png" alt="zoomed in example" width="300" height="216" /></a><p class="wp-caption-text">zoomed in example</p></div>
<p><strong>General Usage</strong></p>
<p>For general usage information please read the README file or <a href="http://code.google.com/p/dodger-editor/wiki/GeneralInformation">General Information</a> page on the google site. It&#8217;s pretty rough right now but hopefully over time we&#8217;ll be able to work on it.</p>
<p><strong>History</strong></p>
<p>If you are interested in the history of this project you can read the following blog posts to see how everything came about:</p>
<ul>
<li><a href="http://www.learningpython.com/2008/02/21/a-simple-python-game-engine/">A Simple Python Game Engine?</a></li>
<li><a href="http://www.learningpython.com/2008/02/24/more-thoughts-on-the-simple-python-game-engine/">More thoughts on the simple Python Game Engine</a></li>
<li><a href="http://www.learningpython.com/2008/03/22/pyglet-level-editor/">Pyglet Level Editor</a></li>
<li><a href="http://www.learningpython.com/2008/04/01/level-editor-02/">Level Editor 0.2</a></li>
<li><a href="http://www.learningpython.com/2008/06/22/level-editor-03-dodger/">Level Editor 0.3 (Dodger)</a></li>
</ul>
<p><strong>Beware</strong></p>
<p>If you do decide to use or test dodger remember that you are going to find a lot of bugs during the iteration. Please be kind and <a href="http://code.google.com/p/dodger-editor/issues/list">report the issue.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2008/08/25/dodger-editor-01/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Back from Holidays</title>
		<link>http://www.learningpython.com/2008/08/18/back-from-holidays-2/</link>
		<comments>http://www.learningpython.com/2008/08/18/back-from-holidays-2/#comments</comments>
		<pubDate>Mon, 18 Aug 2008 22:26:25 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
		
		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=81</guid>
		<description><![CDATA[Sorry about the lack of updates and responses here everyone. I&#8217;ve been away on holidays so I haven&#8217;t had any time to access this blog or work on the level editor at all. I&#8217;m going to try to get the code up as soon as possible so that anyone interested can start playing with it [...]]]></description>
			<content:encoded><![CDATA[<p>Sorry about the lack of updates and responses here everyone. I&#8217;ve been away on holidays so I haven&#8217;t had any time to access this blog or work on the level editor at all. I&#8217;m going to try to get the code up as soon as possible so that anyone interested can start playing with it and hopefully fix all of my mistakes.</p>
<p>Thanks for you patience everyone, I&#8217;ll be back with more soon!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2008/08/18/back-from-holidays-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Level Editor 0.3 (Dodger)</title>
		<link>http://www.learningpython.com/2008/06/22/level-editor-03-dodger/</link>
		<comments>http://www.learningpython.com/2008/06/22/level-editor-03-dodger/#comments</comments>
		<pubDate>Mon, 23 Jun 2008 03:23:27 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
		
		<category><![CDATA[beginnings]]></category>

		<category><![CDATA[game engine]]></category>

		<category><![CDATA[python]]></category>

		<category><![CDATA[Dodger]]></category>

		<category><![CDATA[level editor]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=77</guid>
		<description><![CDATA[I know it&#8217;s been a while and for that I apologize the last few months have been pretty crazy around here&#8230;although I&#8217;m starting to see a trend with life in general lately, namely that it&#8217;s always crazy.
I&#8217;ve been busy with work, Python Magazine, my wife, trips to Dallas, and yes whenever I get a chance [...]]]></description>
			<content:encoded><![CDATA[<p>I know it&#8217;s been a while and for that I apologize the last few months have been pretty crazy around here&#8230;although I&#8217;m starting to see a trend with life in general lately, namely that it&#8217;s always crazy.</p>
<p>I&#8217;ve been busy with work, <a href="http://pymag.phparch.com/">Python Magazine</a>, my wife, trips to Dallas, and yes whenever I get a chance this slowly growing level editor. Let&#8217;s see what I&#8217;ve been working on for the last little while:</p>
<p><strong>Name</strong>: There has a been a name for the editor ever since I started working on it. I wasn&#8217;t sure if I was going to think up something really cool and change, or leave it. Turns out I just left it.</p>
<p>So from this point forward this project is christened: &#8220;Dodger&#8221;, or probably more correctly: &#8220;Dodger Level Editor&#8221;.</p>
<p>The name has its roots in the name of one of my cats and a history in the multitudes of level editors and game engines that I have tried to create in the past, but I wont&#8217; go into that. So Dodger it is.</p>
<p><strong>Saving and Loading</strong>: Saving and loading in the default YAML project type now really works. I still need to put in support for optional project types: XML, JSON, and other formats</p>
<p><a href="http://www.learningpython.com/wp-content/uploads/2008/06/editor_03.png"><img class="alignnone size-medium wp-image-78" title="welcome dialog" src="http://www.learningpython.com/wp-content/uploads/2008/06/editor_03-300x210.png" alt="dodger editor welcome dialog" width="300" height="210" /></a></p>
<p><strong>Welcome Dialog</strong>: This was a real pain, but it&#8217;s made the last while so much easier. I added a working (at least I hope) welcome dialog with a way to create new projects, open old ones, and a recent file list. The recent file list really makes testing easier for me.</p>
<p><a href="http://www.learningpython.com/wp-content/uploads/2008/06/editor_04.png"><img class="alignnone size-medium wp-image-79" title="rect tracking" src="http://www.learningpython.com/wp-content/uploads/2008/06/editor_04-300x210.png" alt="dodger editor rect tracking" width="300" height="210" /></a></p>
<p><strong>Rect tracking</strong>: Rect tracking is finally working properly. I&#8217;ve had the rect tracker in there for a while but it didn&#8217;t really do anything until now.</p>
<p><a href="http://www.learningpython.com/wp-content/uploads/2008/06/editor_05.png"><img class="alignnone size-medium wp-image-80" title="Multiple Selection" src="http://www.learningpython.com/wp-content/uploads/2008/06/editor_05-300x210.png" alt="dodger editor multiple selection" width="300" height="210" /></a></p>
<p><strong>Multiple Selection/Multiple Properties</strong>: I&#8217;ve also finally got multiple selection going, which is what makes the rect tracker actually useful. You can select multiple sprties, move them around and add properties to all of them.</p>
<p><strong>Remove Properties</strong>: Now you can remove custom properties that you have added. This was a must but I was lazy and left it for a while.</p>
<p><strong>Steps towards being made public</strong>: A lot of the changes (and I do mean a lot) that I&#8217;ve been making have been behind the scenes. There has been a lot of refactoring and reorganizing of the code, often the result of quick and dirty implementations that I made earlier (sigh). I&#8217;ve also started working on getting the distribution of this editor going so that other people can use/develop it.</p>
<p>I&#8217;ve added support for zc.Buildout so that if anyone wants to develop they can quickly gather dependencies and won&#8217;t have to install the editor system wide, not that you have to anyways but zc.Buildout is really neat.</p>
<p>I&#8217;ve also worked on the license (GPLv3) and setup.py and README and all of that. None of it&#8217;s done but it&#8217;s working its way forward.</p>
<p><strong>Faster</strong>: It&#8217;s also much faster now. None of you have used it so you&#8217;ll probably think it&#8217;s slow, but trust me it&#8217;s much faster then it was before.</p>
<p><strong>Bugs</strong>: There have been loads of bugs that have been fixed and created. Plus one doozy related to<br />
changes made to pyglet. Not pyglets fault but it took a long time to figure out what the issue was.</p>
<p><strong>Google Code</strong>: The project has a temporary homepage over at google code: <a href="http://code.google.com/p/dodger-editor/">http://code.google.com/p/dodger-editor/</a> There&#8217;s nothing there yet but over time I will start to host the project there so that people can easily download it. I&#8217;ll still post updates here until the site has a full-time home.</p>
<p>I&#8217;m going to use Mercurial for the revision control system for the project so the CVS support at the google code site will just be for downloading. Eventually I will want to host the project on some space of my own and get a nice web interface for the mercurial repository going. I&#8217;ll have to find a new hosting company so it will take a while.</p>
<p>So that&#8217;s it, that&#8217;s what&#8217;s happened to the Dodger Level Editor over the last few months. I know I promised to make it public earlier but given the shape it was in at that time there really was no point. I want this to be at a point where people can actually almost use it before I make it public.</p>
<p>I know it&#8217;s been a while, and I know the few of you that actually care about this project have probably moved onto bigger and better things, but hopefully if you stick with me there will be something out soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2008/06/22/level-editor-03-dodger/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Operator Overload! Learn how to change the behavior of equality operators.</title>
		<link>http://www.learningpython.com/2008/06/21/operator-overload-learn-how-to-change-the-behavior-of-equality-operators/</link>
		<comments>http://www.learningpython.com/2008/06/21/operator-overload-learn-how-to-change-the-behavior-of-equality-operators/#comments</comments>
		<pubDate>Sat, 21 Jun 2008 15:21:49 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
		
		<category><![CDATA[Python Magazine]]></category>

		<category><![CDATA[python]]></category>

		<category><![CDATA[equality]]></category>

		<category><![CDATA[operator]]></category>

		<category><![CDATA[overload]]></category>

		<category><![CDATA[PythonMagazine]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=76</guid>
		<description><![CDATA[By: Mark Mruss
Note: This article was first published the November 2007 issue of Python Magazine
While the equality operator works great on numbers and strings the fact the way it treats your custom objects really is not that useful. This article looks into overloading the equality operator so that you can easily compare your custom classes.

Introduction
Introducing [...]]]></description>
			<content:encoded><![CDATA[<p><strong>By: Mark Mruss</strong></p>
<p><strong>Note:</strong> This article was first published the November 2007 issue of <a href="http://www.pythonmagazine.com">Python Magazine</a></p>
<p>While the equality operator works great on numbers and strings the fact the way it treats your custom objects really is not that useful. This article looks into overloading the equality operator so that you can easily compare your custom classes.</p>
<ol>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#Introducing">Introducing the terms: operators and operator overloading</a></li>
<li><a href="#QuickExample">A Quick Example of the Default Equality Operator</a></li>
<li><a href="#Overloading">Overloading the Equality Operator</a></li>
<li><a href="#NotImplemented">Telling Python that the Comparison has Not Been Implemented</a></li>
<li><a href="#InequalityOperator">The Inequality Operator</a></li>
<li><a href="#Dangers">Dangers</a></li>
<li><a href="#Conclusion">Conclusion</a></li>
</ol>
<p><span id="more-76"></span></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>In my experience as a professional programmer, testing for the equality between two instances of a class is a fairly common task. In other words, you are comparing the data that each class contains and checking whether the data in one class is identical to the data in the other class.</p>
<p>One of the nice features of Python is that it has a default equality operator defined for any custom objects that you create. The unfortunate thing about this default equality operator is that it doesn’t provide the functionality that you expect. This is because the equality operator (==) actually performs an identity comparison, rather than an equivalence test. If you were to run the following code:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">object_one</span><span class="hl-code"> == </span><span class="hl-identifier">object_two</span><span class="hl-brackets">)</span><span class="hl-default">:</span></pre></div></div>
<p>By default Python actually compares whether or not <code>object_one</code> <strong>is</strong> <code>object_two</code> (this is the same comparison that can be made using the <code>is</code> keyword) instead of determining whether or not <code>object_one</code> is equivalent to <code>object_two</code>. Fortunately for us, overloading the default equality operator in Python is a relatively easy task. There are, however, some &#8220;gotchas&#8221; and other interesting features of which one should be aware.</p>
<h2><a name="Introducing">Introducing the terms: operators and operator overloading</a></h2>
<p>An operator can be difficult to define, and like many programming definitions, sometimes the definition only serves to confuse the matter further. In general though, you can think of operators as being very similar to the operators that you encountered in Math class, such as: the + operator, the - operator, and so forth.</p>
<p>In Python the following are operators<a href="#1">[1]</a>:</p>
<pre>
+	-	*	<strong>	/	//	%	<>>	&#038;
|	^	~	<>	< =	>=	==	!=	<>
</strong></pre>
<p>In programming languages we generally encounter binary operators. This means that each operator takes two operands. An operand serves as input to an operator. For example, in the statement:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-number">2</span><span class="hl-default"> + </span><span class="hl-number">6</span></pre></div></div>
<p>+ is a binary operator that takes two operands, 2 and 6 as inputs. Similarly, in this statement:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">my_value</span><span class="hl-default"> - </span><span class="hl-number">6</span></pre></div></div>
<p>- is an operator that takes two operands, <code>my_value</code> and 6 as inputs.</p>
<p>Operator overloading is a programming term that means taking the default behaviour of an operator and overloading it. That is, changing the default implementation of an operator for a given object. An example of this (although something that you should never do) would be to overload the + operator to actually perform subtraction instead when it is applied to your class. </p>
<h2><a name="QuickExample">A Quick Example of the Default Equality Operator</a></h2>
<p>Now that the definitions are out of the way, let&#8217;s look at an example where one might want to overload the equality operator. For this example I will bring back a favourite example from my Computer Science days: the <code>Student</code> class:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">Student</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">name</span><span class="hl-code">, </span><span class="hl-identifier">student_number</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">name</span><span class="hl-default"> = </span><span class="hl-identifier">name
		self</span><span class="hl-default">.</span><span class="hl-identifier">student_number</span><span class="hl-default"> = </span><span class="hl-identifier">student_number</span></pre></div></div>
<p>As you can see the <code>Student</code> class has two data members: 1) the student&#8217;s name, and, 2) her student number.</p>
<p>If we run the following code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">mark</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Mark Mruss</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">067213</span><span class="hl-brackets">)
</span><span class="hl-identifier">guido</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Guido van Rossum</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">000001</span><span class="hl-brackets">)
</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">mark</span><span class="hl-code"> == </span><span class="hl-identifier">guido</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">Equal</span><span class="hl-quotes">&quot;
</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">Not Equal</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>&#8220;Not Equal&#8221; will be printed out as you would expect since the two students are clearly not equivalent. But what about this code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">mark</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Mark Mruss</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">067213</span><span class="hl-brackets">)
</span><span class="hl-identifier">mark_two</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Mark Mruss</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">067213</span><span class="hl-brackets">)
</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">mark</span><span class="hl-code"> == </span><span class="hl-identifier">mark_two</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">Equal</span><span class="hl-quotes">&quot;
</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">Not Equal</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>Here, as in the previous example, &#8220;Not Equal&#8221; will be printed out. This is because, as mentioned earlier, the default implementation of the equality operator is to perform an identity comparison. In other words, the default equality operator asks, is <code>mark</code> the same object as <code>mark_two</code>? In Python the equality comparison depends on the type of objects being compared. For custom classes that you or I will create, the equality comparison will perform an identity comparison by comparing the object’s internal id. In other words, it will only result in True if the objects being compared actually <strong>are</strong> each other. For example:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">student_one</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Mark Mruss</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">067213</span><span class="hl-brackets">)
</span><span class="hl-identifier">student_two</span><span class="hl-default"> = </span><span class="hl-identifier">student_one
if </span><span class="hl-brackets">(</span><span class="hl-identifier">student_one</span><span class="hl-code"> == </span><span class="hl-identifier">student_two</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">Equal</span><span class="hl-quotes">&quot;
</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">Not Equal</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>Results in &#8220;Equal&#8221; being printed out, as would:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">student_one</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Mark Mruss</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">067213</span><span class="hl-brackets">)
</span><span class="hl-identifier">student_two</span><span class="hl-default"> = </span><span class="hl-identifier">student_one
if </span><span class="hl-brackets">(</span><span class="hl-builtin">id</span><span class="hl-brackets">(</span><span class="hl-identifier">student_one</span><span class="hl-brackets">)</span><span class="hl-code"> == </span><span class="hl-builtin">id</span><span class="hl-brackets">(</span><span class="hl-identifier">student_two</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">Equal</span><span class="hl-quotes">&quot;
</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">Not Equal</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p><strong>Note:</strong> The equality comparison for built-in objects and types like numbers, strings, lists, tuples, and mappings behave differently. Numbers are compared arithmetically. The numerical values of the characters within strings are compared arithmetically. The comparison of lists and tuples is simply a comparison of their inner values, while the comparison of mappings are comparisons of an ordered list of their values.<a href="#2">[2]</a></p>
<h2><a name="Overloading">Overloading the Equality Operator</a></h2>
<p>Hopefully the above example illustrated a case where we might want to overload the equality operator to make it so that the following code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">student_one</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Mark Mruss</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">067213</span><span class="hl-brackets">)
</span><span class="hl-identifier">student_two</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Mark Mruss</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">067213</span><span class="hl-brackets">)
</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">student_one</span><span class="hl-code"> == </span><span class="hl-identifier">student_two</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">Equal</span><span class="hl-quotes">&quot;
</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">Not Equal</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>Would result in &#8220;Equal&#8221; being printed out, i.e. a true equality comparison as opposed to an identity comparison. In order to do this we need to change to the default functionality of the equality operator. In other words we need to overload it.</p>
<p>In general, operator overloading in Python means adding a special function to your class that will perform the function of the operator it is meant to represent. There are two ways in which one can overload the equality operator in Python: 1) the first method is to use the <code>__eq__</code> function, a so-called &#8220;rich comparison&#8221; function. &#8220;Rich comparison&#8221; functions are functions that overload specific comparison operators (i.e. <code>__eq__</code> to overload ==). 2) The second is to use the <code>__cmp__</code> function, which is used to overload all comparison operators if no &#8220;rich comparison&#8221; functions are present.  </p>
<p>Since <code>__cmp__</code> is used to override all comparison operators (<code>==, !=, < , <=, >, >=</code>), I would suggest using the &#8220;rich comparison&#8221; method unless you are using a version of Python that is earlier then version 2.1, or you are convinced that you know what <code>< =</code> means to our </code><code>Student</code> class. Let&#8217;s forget about the <code>__cmp__</code> operator for now and focus on using the &#8220;rich comparison&#8221; functions to overload the equality operator. </p>
<p>&#8220;Rich comparison&#8221; functions can return any value, but you should try to return a value that is, or can be, interpreted as a boolean value. This is important because these functions will often be used in situations where the return value will be used in a boolean comparison. </p>
<p>When using the &#8220;rich comparison&#8221; functions it is important to know which functions are being called internally. For example, when we run:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">student_one</span><span class="hl-default"> == </span><span class="hl-identifier">student_two</span></pre></div></div>
<p>If <code>__eq__</code> exists in the <code>Student</code> class, the following is actually being called:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">student_one</span><span class="hl-default">.</span><span class="hl-identifier">__eq__</span><span class="hl-brackets">(</span><span class="hl-identifier">student_two</span><span class="hl-brackets">)</span></pre></div></div>
<p>When we run:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">student_two</span><span class="hl-default"> == </span><span class="hl-identifier">student_one</span></pre></div></div>
<p>The following is actually called:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">student_two</span><span class="hl-default">.</span><span class="hl-identifier">__eq__</span><span class="hl-brackets">(</span><span class="hl-identifier">student_one</span><span class="hl-brackets">)</span></pre></div></div>
<p>As you can see it is the operand on the left-hand side whose <code>__eq__</code> function will be called. It is important to note that if the operand on the left-hand side lacks the <code>__eq__</code> function while the operand on the right-hand side has one, the right-hand operand&#8217;s <code>__eq__</code> function will not be called.</p>
<p>Lets start off with a simple, but incorrect, example (the reasons for its incorrectness will be explained below):</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">__eq__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">other</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-identifier">return </span><span class="hl-brackets">((</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-code"> == </span><span class="hl-identifier">other</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-brackets">)
		</span><span class="hl-identifier">and </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">student_number</span><span class="hl-code"> == </span><span class="hl-identifier">other</span><span class="hl-code">.</span><span class="hl-identifier">student_number</span><span class="hl-brackets">))</span></pre></div></div>
<p>This is very straightforward. In the equality comparison, we simply compare the <code>Student</code> class&#8217; two data members. This performs as expected when we run:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">student_one</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Mark Mruss</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">067213</span><span class="hl-brackets">)
</span><span class="hl-identifier">student_two</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Guido van Rossum</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">000001</span><span class="hl-brackets">)
</span><span class="hl-identifier">student_three</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Mark Mruss</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">000001</span><span class="hl-brackets">)
</span><span class="hl-identifier">print </span><span class="hl-brackets">(</span><span class="hl-identifier">student_one</span><span class="hl-code"> == </span><span class="hl-identifier">student_two</span><span class="hl-brackets">)
</span><span class="hl-identifier">print </span><span class="hl-brackets">(</span><span class="hl-identifier">student_one</span><span class="hl-code"> == </span><span class="hl-identifier">student_three</span><span class="hl-brackets">)</span></pre></div></div>
<p>You get:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">False
True</span></pre></div></div>
<p>But what happens when we introduce the <code>Professor</code> class and try the overloaded equality operator:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">Professor</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">instructor</span><span class="hl-code">, </span><span class="hl-identifier">course</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">instructor</span><span class="hl-default"> = </span><span class="hl-identifier">instructor
		self</span><span class="hl-default">.</span><span class="hl-identifier">course</span><span class="hl-default"> = </span><span class="hl-identifier">course</span></pre></div></div>
<p>As you can see, the <code>Professor</code> class lacks the <code>name</code> and <code>student_number</code> data members. What happens when we compare an instance of the <code>Professor</code> class with an instance of the <code>Student</code> class?</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">guido</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Guido van Rossum</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">000001</span><span class="hl-brackets">)
</span><span class="hl-identifier">rob</span><span class="hl-default"> = </span><span class="hl-identifier">Professor</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Rob Ward</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">74-300</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">print </span><span class="hl-brackets">(</span><span class="hl-identifier">guido</span><span class="hl-code"> == </span><span class="hl-identifier">rob</span><span class="hl-brackets">)</span></pre></div></div>
<p>It results in something like this:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">File </span><span class="hl-quotes">&quot;</span><span class="hl-string">operators.py</span><span class="hl-quotes">&quot;</span><span class="hl-default">, </span><span class="hl-identifier">line </span><span class="hl-number">10</span><span class="hl-default">, </span><span class="hl-reserved">in </span><span class="hl-identifier">__eq__
    return </span><span class="hl-brackets">((</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-code"> == </span><span class="hl-identifier">other</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-brackets">)
</span><span class="hl-reserved">AttributeError</span><span class="hl-code">: </span><span class="hl-quotes">'</span><span class="hl-string">Professor</span><span class="hl-quotes">' </span><span class="hl-identifier">object has no attribute </span><span class="hl-quotes">'</span><span class="hl-string">name</span><span class="hl-quotes">'</span></pre></div></div>
<p>The way we are overriding the equality operator is not correct because it automatically assumes that the other object has the <code>name</code> and <code>student_number</code> data members. There are a number of methods to get around this problem, including: 1) using the <code>hasattr</code> function, or 2) using the <code>isinstance</code> function.  Using the <code>hasattr</code> function determines if <code>other</code> has the attributes we are looking for before actually querying them.  <code>hasattr</code> simply tells us if an object has a specific attribute or not. Here is a quick example illustrating how to do this:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">__eq__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">other</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-builtin">hasattr</span><span class="hl-brackets">(</span><span class="hl-identifier">other</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">name</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">) </span><span class="hl-reserved">and </span><span class="hl-builtin">hasattr</span><span class="hl-brackets">(</span><span class="hl-identifier">other</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">student_number</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">))</span><span class="hl-default">:
		</span><span class="hl-identifier">return </span><span class="hl-brackets">((</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-code"> == </span><span class="hl-identifier">other</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-brackets">)
			</span><span class="hl-identifier">and </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">student_number</span><span class="hl-code"> == </span><span class="hl-identifier">other</span><span class="hl-code">.</span><span class="hl-identifier">student_number</span><span class="hl-brackets">))
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-reserved">return False</span></pre></div></div>
<p>First, we check to see if <code>other</code> has the <code>name</code> and <code>student_number</code> attributes. If it does, we proceed as normal. If it does not, we simply return false.  When we compare the professor and the student we get &#8220;False&#8221; as expected.</p>
<p>What&#8217;s nice about this method is that we don&#8217;t have to care what type <code>other</code> is. We only care whether or not it contains the attributes we need to compare. However, the drawback to this function is that you have to test for the existence of each attribute. Although this may not always be a big deal, if you are dealing with fifty data members in your classes this can quickly become a pain in the neck.</p>
<p>Another solution to the problem with our first overloading example is to use the <code>isinstance</code> function to make sure that <code>other</code> is an instance of our class type. This has the drawback of forcing <code>other</code> to be the same type as your class. In practice however, I believe this to be more of an advantage than a disadvantage.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">__eq__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">other</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-builtin">isinstance</span><span class="hl-brackets">(</span><span class="hl-identifier">other</span><span class="hl-code">, </span><span class="hl-identifier">Student</span><span class="hl-brackets">))</span><span class="hl-default">:
		</span><span class="hl-identifier">return </span><span class="hl-brackets">((</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-code"> == </span><span class="hl-identifier">other</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-brackets">)
			</span><span class="hl-identifier">and </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">student_number</span><span class="hl-code"> == </span><span class="hl-identifier">other</span><span class="hl-code">.</span><span class="hl-identifier">student_number</span><span class="hl-brackets">))
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-reserved">return False</span></pre></div></div>
<p>The first thing we do is check the variable <code>other</code> to make sure that it is an instance of the <code>Student</code> class.  If it is, we then compare all of the data members in the <code>Student</code> class.  If <code>object</code> is not an instance of the <code>Student</code> class, we return <code>False</code>.</p>
<p>In my opinion, this is the preferred method since knowing that the class is the correct type is often important. The <code>hasattr</code> method seems more appropriate for simple data containers like a &#8220;rect&#8221; or &#8220;vector&#8221; class where you are only interested in three or four data members.</p>
<h2><a name="NotImplemented">Telling Python that the Comparison has Not Been Implemented</a></h2>
<p>Up until this point in time we have been returning <code>False</code> when our <code>__eq__</code> function does not support the type of object passed in as <code>other</code>. While this is acceptable and correct given the Python documentation, it seems to be &#8220;proper&#8221; to actually return <code>NotImplemented</code>.  According to the Python documentation, &#8220;Numeric methods and rich comparison methods may return this value if they do not implement the operation for the operands provided. (The interpreter will then try the reflected operation, or some other fallback, depending on the operator.)&#8221; <a href="#4">[4]</a>Let&#8217;s forget abou In other words, if the left operand returns <code>NotImplemented</code>, Python will attempt to use the right hand operand&#8217;s equality operator. And if that does not exist, Python will fall back to the default equality operator.</p>
<p>We can return <code>NotImplemted</code> from our <code>Student</code> class if the operand passed in is not an instance of the <code>Student</code>:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">_eq__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">other</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-builtin">isinstance</span><span class="hl-brackets">(</span><span class="hl-identifier">other</span><span class="hl-code">, </span><span class="hl-identifier">Student</span><span class="hl-brackets">))</span><span class="hl-default">:
		</span><span class="hl-identifier">return </span><span class="hl-brackets">((</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-code"> == </span><span class="hl-identifier">other</span><span class="hl-code">.</span><span class="hl-identifier">name</span><span class="hl-brackets">)
			</span><span class="hl-identifier">and </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">student_number</span><span class="hl-code"> == </span><span class="hl-identifier">other</span><span class="hl-code">.</span><span class="hl-identifier">student_number</span><span class="hl-brackets">))
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-reserved">return NotImplemented</span></pre></div></div>
<p>Now if we perform the following comparison:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">guido</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Guido van Rossum</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">000001</span><span class="hl-brackets">)
</span><span class="hl-identifier">rob</span><span class="hl-default"> = </span><span class="hl-identifier">Professor</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Rob Ward</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">74-300</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">print </span><span class="hl-identifier">guido</span><span class="hl-default"> == </span><span class="hl-identifier">rob</span></pre></div></div>
<p>The first step in the processing will be:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">guido</span><span class="hl-default">.</span><span class="hl-identifier">__eq__</span><span class="hl-brackets">(</span><span class="hl-identifier">rob</span><span class="hl-brackets">)</span></pre></div></div>
<p>This returns <code>NotImplemented</code>. As a result, the reflected operation is attempted: </p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">rob</span><span class="hl-default"> == </span><span class="hl-identifier">guido</span></pre></div></div>
<p>Because the <code>Professor</code> class does not have the equality operator overloaded, the default operation is executed and <code>False</code> is printed out just like we wanted.</p>
<p><code>NotImplemented</code> is useful in because instead of returning <code>False</code>, which means that the two operand are not equivalent, you return a value that says that the comparison between the operands has not been implemented.</p>
<h2><a name="InequalityOperator">The Inequality Operator</a></h2>
<p>Now that we know how to overload the equality operator, it stands to reason that we have the opposite operation, the inequality operator (!=) covered as well. But not so fast. In Python the inequality and equality operators are handled separately, meaning that inequality is not simply the opposite of equality.  This means that whenever you overload the equality operator, you have to be sure to overload the inequality operator as well. If you don&#8217;t you might get some strange results. For example, when we use the current code (without the inequality operator overloaded), the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">guido</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Guido van Rossum</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">000001</span><span class="hl-brackets">)
</span><span class="hl-identifier">guido_too</span><span class="hl-default"> = </span><span class="hl-identifier">Student</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Guido van Rossum</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-number">000001</span><span class="hl-brackets">)
</span><span class="hl-reserved">print </span><span class="hl-identifier">guido</span><span class="hl-default"> == </span><span class="hl-identifier">guido_too
</span><span class="hl-reserved">print </span><span class="hl-identifier">guido</span><span class="hl-default"> != </span><span class="hl-identifier">guido_too</span></pre></div></div>
<p>Results in:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">True
True</span></pre></div></div>
<p>In the first comparison the overloaded equality operator is used, and results in <code>True</code> being printed. Because the inequality operator is not overloaded in the second comparison, the default inequality operator is used (the identity comparison). <code>True</code> is printed because <code>guido</code> and <code>guido_too</code> are not the same instances.</p>
<p>Thankfully once you have overloaded the equality operator, overloading the inequality operator is very easy. As a general rule, you have to return the opposite of the equality operator, but because we are working with <code>NotImplemented</code>, we have to do a bit more processing to ensure that we don&#8217;t return <code>False</code> when we really want to return <code>NotImplemented</code>. Here is how we can overload the inequality operator in the <code>Student</code> class:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">__ne__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">other</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-identifier">equal_result</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">__eq__</span><span class="hl-brackets">(</span><span class="hl-identifier">other</span><span class="hl-brackets">)
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">equal_result </span><span class="hl-reserved">is not NotImplemented</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-reserved">return not </span><span class="hl-identifier">equal_result
	</span><span class="hl-reserved">return NotImplemented</span></pre></div></div>
<p>First, we call <code>self.__eq__</code> to test whether or not we are equal to <code>other</code>. We then check to make sure that <code>equal_result</code> is not <code>NotImplemented</code>. If it is not, we know that the equality test was implemented and we can safely return its’ opposite. If the result for the equality comparison was <code>NotImplemented</code>, we return <code>NotImplemented</code> for the inequality comparison.</p>
<p><strong>Note:</strong> It is safe to use the <code>is</code> check on <code>NotImplemented</code> (rather than an <code>isinstance</code> check) because <code>NotImplemented</code> is a singleton, meaning that there is only ever one instance of <code>NotImplemented</code> at anytime.</p>
<h2><a name="Dangers">Dangers</a></h2>
<p>While it may seem like operator overloading should become part of every class that you write, a word of warning is necessary. There is a large school of thought that views operator overloading as a dangerous programming technique. They argue that overloading operators changes the default way that an operator works, and not always correctly. Moreover, instead of overriding the equality operator, one can simply add an <code>is_equal_to</code> function to perform the equality check.</p>
<p>The logic behind this criticism is that when someone is using a class or reading some code that you wrote, they will be unable to tell what the equality operator is doing. For example, if they see:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">value</span><span class="hl-default"> = </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">(</span><span class="hl-number">10</span><span class="hl-brackets">)
</span><span class="hl-identifier">value_two</span><span class="hl-default"> = </span><span class="hl-identifier">MyClass</span><span class="hl-brackets">(</span><span class="hl-number">10</span><span class="hl-brackets">)
</span><span class="hl-reserved">print </span><span class="hl-identifier">value</span><span class="hl-default"> == </span><span class="hl-identifier">value_two</span></pre></div></div>
<p>What gets printed out? True or False?  If “MyClass” overrode the equality operator then True will be printed. However, if the equality operator is not overloaded, the standard Python behaviour of equality will result with False being printed out. </p>
<h2><a name="Conclusion">Conclusion</a></h2>
<p>While it&#8217;s true that overloading the equality operator does change the default way the Python functions, I feel that it&#8217;s generally a safe and beneficial addition to your classes. Especially since unless people know the ins and outs of the equality operator they will generally assume that should work the way it does when you overload it. Like all the decisions that you make when working with Python, context is key.</p>
<p><a name="1">[1]</a> <a href="http://docs.python.org/ref/operators.html">http://docs.python.org/ref/operators.html</a><br />
<a name="2">[2]</a> <a href="http://docs.python.org/ref/comparisons.html">http://docs.python.org/ref/comparisons.html</a><br />
<a name="3">[3]</a> <a href="http://docs.python.org/ref/customization.html">http://docs.python.org/ref/customization.html</a><br />
<a name="4">[4]</a> <a href="http://docs.python.org/ref/types.html">http://docs.python.org/ref/types.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2008/06/21/operator-overload-learn-how-to-change-the-behavior-of-equality-operators/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Possible hackage</title>
		<link>http://www.learningpython.com/2008/05/30/possible-hackage/</link>
		<comments>http://www.learningpython.com/2008/05/30/possible-hackage/#comments</comments>
		<pubDate>Fri, 30 May 2008 20:37:16 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
		
		<category><![CDATA[News]]></category>

		<category><![CDATA[hackers]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=75</guid>
		<description><![CDATA[Note: The blog was hacked. I spent all night trying to clean it up. If you have registered here you may think about changing your password. Sorry about this folks it pretty much sucks.
Hey everyone,
Just to let you know there is a strong possibility that this blog was hacked recently.  A helpful user (Eoin) [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Note: </strong>The blog was hacked. I spent all night trying to clean it up. If you have registered here you may think about changing your password. Sorry about this folks it pretty much sucks.</p>
<p>Hey everyone,</p>
<p>Just to let you know there is a strong possibility that this blog was hacked recently.  A helpful user (Eoin) informed me that when trying to visit the blog from Google he was re-directed to an advertising website.</p>
<p>In response I&#8217;ve updated the blog and tried my best to ensure that anything that was hacked is back to normal.</p>
<p>If anyone noticed anything strange happening on this blog please let me know.</p>
<p>Thanks.</p>
<p>Fraking hackers&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2008/05/30/possible-hackage/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Elegant XML parsing using the ElementTree Module</title>
		<link>http://www.learningpython.com/2008/05/07/elegant-xml-parsing-using-the-elementtree-module/</link>
		<comments>http://www.learningpython.com/2008/05/07/elegant-xml-parsing-using-the-elementtree-module/#comments</comments>
		<pubDate>Wed, 07 May 2008 16:21:48 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[python]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[xml]]></category>

		<category><![CDATA[ElementTree]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=74</guid>
		<description><![CDATA[Mark Mruss
Note: This article was first published the October 2007 issue of Python Magazine
XML is everywhere.  It seems you can&#8217;t do much these days unless you utilize XML in one way or another. Fortunately, Python developers have a new tool in our standard arsenal: the ElementTree module. This article aims to introduce you to [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Mark Mruss</strong></p>
<p><strong>Note:</strong> This article was first published the October 2007 issue of <a href="http://www.pythonmagazine.com">Python Magazine</a></p>
<p>XML is everywhere.  It seems you can&#8217;t do much these days unless you utilize XML in one way or another. Fortunately, Python developers have a new tool in our standard arsenal: the ElementTree module. This article aims to introduce you to reading, writing, saving, and loading XML using the ElementTree module.</p>
<ol>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#ReadingXMLdata">Reading XML data</a></li>
<li><a href="#Listing1">Listing 1</a></li>
<li><a href="#Listing2">Listing 2</a></li>
<li><a href="#ReadingXMLAttributes">Reading XML Attributes</a></li>
<li><a href="#WritingXML">Writing XML</a></li>
<li><a href="#Listing3">Listing 3</a></li>
<li><a href="#WritingXMLAttributes">Writing XML Attributes</a></li>
<li><a href="#ReadingXMLFiles">Reading XML Files</a></li>
<li><a href="#WritingXMLDatatoaFile">Writing XML Data to a File</a></li>
<li><a href="#ReadingfromtheWeb">Reading from the Web</a></li>
<li><a href="#Conclusion">Conclusion</a></li>
</ol>
<p><span id="more-74"></span><!--more--></p>
<h2><a href="#Introduction">Introduction</a></h2>
<p>It seems like everyone needs to parse XML these days.  They&#8217;re either saving their own information in XML or loading in someone else&#8217;s data.  This is why I was glad to learn that as of Python 2.5, the <em>ElementTree</em> XML package has been added to the standard library in the XML module.</p>
<p>What I like about the <em>ElementTree</em> module is that it just seems to make sense.  This might seem like a strange thing to say about an XML module, but I&#8217;ve had to parse enough XML in my time to know that if an XML module makes sense the first time you use it, it&#8217;s probably a keeper. The <em>ElementTree</em> module allows me to work with XML data in a way that is similar to how I <em>think</em> about XML data.</p>
<p>A subset of the full <em>ElementTree</em> module is available in the Python 2.5 standard library as <code>xml.etree</code>, but you don&#8217;t have to use Python 2.5 in order to use the <em>ElementTree</em> module. If you are still using an older version of Python (1.5.2 or later) you can simply download the module from its website and manually install it on your system.  The website also has very easy to follow installation instructions, which you should consult to avoid issues while installing <em>ElementTree</em>.</p>
<p>In general, the <em>ElementTree</em> module treats XML data as a list of lists.  All XML has a root element that will have zero or more subelements (or child elements). Each of those subelements may in turn have subelements of their own.  The best way to think about this is with a brief example.</p>
<p>First let&#8217;s take a look at some sample XML data:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">&lt;</span><span class="hl-identifier">root</span><span class="hl-default">&gt;
&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">One</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;
&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">Two</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;
&lt;/</span><span class="hl-identifier">root</span><span class="hl-default">&gt;</span></pre></div></div>
<p>Here we have a root element with two child elements. Each child element has some text associated with it seen here as &#8220;one&#8221; and &#8220;two&#8221;. If we examine the XML as a hierarchical list of lists we see that we have one element &#8220;root&#8221; in our root list.  Within the &#8220;root&#8221; element we have a list containing two subelements &#8220;child&#8221; and &#8220;child&#8221;. The two &#8220;child&#8221; elements would then contain empty lists representing their lack of subelements. Not too complicated so far, is it?</p>
<h2><a href="#ReadingXMLdata">Reading XML data</a></h2>
<p>Now let&#8217;s use the <em>ElementTree</em> package to parse this XML and print the text data associated with each child element.  To start, we&#8217;ll create a Python file with the contents shown in Listing 1.</p>
<p><strong><a href="#Listing1">Listing 1</a></strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python

</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">pass

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>This is basically a template that I use for many of my simple &#8220;*.py&#8221; files.  It doesn&#8217;t actually do anything except set up the script so that when the file is run, the <code>main</code> method will be executed. Some people like to use the Python interactive interpreter for simple hacking like this. Personally, I prefer having my code stored in a handy file so I can make simple changes and re-run the entire script when I am just playing around.</p>
<p>The first thing that we need to do in our Python code is import the <em>ElementTree</em> module:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">xml</span><span class="hl-default">.</span><span class="hl-identifier">etree </span><span class="hl-reserved">import </span><span class="hl-identifier">ElementTree as ET</span></pre></div></div>
<p><strong>Note</strong>: If you are not using Python 2.5 and have installed the <em>ElementTree</em> module on your own, you should import the <em>ElementTree</em> module as follows:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">from </span><span class="hl-identifier">elementtree </span><span class="hl-reserved">import </span><span class="hl-identifier">ElementTree as ET</span></pre></div></div>
<p>This will import the ElementTree section of the module into your program aliased as ET.  However, you don&#8217;t have to import <em>ElementTree</em> using an alias; you can simply import it and access it as <code>ElementTree</code>. Using ET is demonstrated in the Python 2.5 &#8220;What&#8217;s new&#8221; documentation[1] and I think it&#8217;s a great way to eliminate some key strokes.</p>
<p>Now we&#8217;ll begin writing code in the <code>main</code> method.  The first step is to load the XML data described above.  Normally you will be working with a file or URL; for now we want to keep this simple and load the XML data directly from the text:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">element</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(
       </span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;root&gt;&lt;child&gt;One&lt;/child&gt;&lt;child&gt;Two&lt;/child&gt;&lt;/root&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>The <code>XML</code> function is described in the <em>ElementTree</em> documentation as follows: &#8220;Parses an XML document from a string constant. This function can be used to embed &#8220;XML literals&#8221; in Python code&#8221;[2].</p>
<p>Be careful here! The <code>XML</code> function returns an Element object, and not an ElementTree object as one might expect. Element objects are used to represent XML elements, whereas the ElementTree object is used to represent the entire XML document. Element objects <em>may</em> represent the entire XML document if they are the root element but will not if they are a subelement. ElementTree objects also add &#8220;some extra support for serialization to and from standard XML.&#8221;[3] The Element object that is returned represents the <code><root></root></code> element in our XML data.</p>
<p>Thankfully, the Element object is an iterator object so we can use a <code>for</code> loop to loop through all of its child elements:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">for </span><span class="hl-identifier">subelement </span><span class="hl-reserved">in </span><span class="hl-identifier">element</span><span class="hl-default">:</span></pre></div></div>
<p>This will give us all the child elements in the root element.  As mentioned earlier, each element in the XML tree is represented as an Element object, so as we iterate through the root element&#8217;s child elements we are getting Element objects with which to work. Meaning that each loop though the for loop will give us the next child element in the form of an Element object until there are no more children left. In order to print out the text associated with an Element object we simply have to access the Element object&#8217;s <code>text</code> attribute:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">for </span><span class="hl-identifier">subelement </span><span class="hl-reserved">in </span><span class="hl-identifier">element</span><span class="hl-default">:
       </span><span class="hl-reserved">print </span><span class="hl-identifier">subelement</span><span class="hl-default">.</span><span class="hl-identifier">text</span></pre></div></div>
<p>To recap, have a look at the code in Listing 2.</p>
<p><strong><a href="#Listing2">Listing 2</a></strong></p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python

</span><span class="hl-reserved">from </span><span class="hl-identifier">xml</span><span class="hl-default">.</span><span class="hl-identifier">etree </span><span class="hl-reserved">import </span><span class="hl-identifier">ElementTree as ET

</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">element</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;root&gt;&lt;child&gt;One&lt;/child&gt;&lt;child&gt;Two&lt;/child&gt;&lt;/root&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-reserved">for </span><span class="hl-identifier">subelement </span><span class="hl-reserved">in </span><span class="hl-identifier">element</span><span class="hl-default">:
		</span><span class="hl-reserved">print </span><span class="hl-identifier">subelement</span><span class="hl-default">.</span><span class="hl-identifier">text

</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>Once you run the code you should get the following output:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">One
Two</span></pre></div></div>
<p>If an XML element does not have any text associated with it, like our root element, the Element object&#8217;s <code>text</code> attribute will be set to <code>None</code>. If you want to check if an element had any text associated with it, you can do the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">if </span><span class="hl-identifier">element</span><span class="hl-default">.</span><span class="hl-identifier">text </span><span class="hl-reserved">is not None</span><span class="hl-default">:
       </span><span class="hl-reserved">print </span><span class="hl-identifier">element</span><span class="hl-default">.</span><span class="hl-identifier">text</span></pre></div></div>
<h2><a href="#ReadingXMLAttributes">Reading XML Attributes</a></h2>
<p>Let&#8217;s alter the XML that we are working with to add attributes to the elements and look at how we would parse that information.</p>
<p>If the XML uses attributes in addition to, or instead of, inner text they can be accessed using the Element object&#8217;s <code>attrib</code> attribute.  The <code>attrib</code> attribute is a Python dictionary and is relatively easy to use:</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">element</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(
               </span><span class="hl-quotes">'</span><span class="hl-string">&lt;root&gt;&lt;child val=&quot;One&quot;/&gt;&lt;child val=&quot;Two&quot;/&gt;&lt;/root&gt;</span><span class="hl-quotes">'</span><span class="hl-brackets">)
       </span><span class="hl-reserved">for </span><span class="hl-identifier">subelement </span><span class="hl-reserved">in </span><span class="hl-identifier">element</span><span class="hl-default">:
               </span><span class="hl-reserved">print </span><span class="hl-identifier">subelement</span><span class="hl-default">.</span><span class="hl-identifier">attrib</span></pre></div></div>
<p>When you run the code you get the following output:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">{</span><span class="hl-quotes">'</span><span class="hl-string">val</span><span class="hl-quotes">'</span><span class="hl-default">: </span><span class="hl-quotes">'</span><span class="hl-string">One</span><span class="hl-quotes">'</span><span class="hl-default">}
{</span><span class="hl-quotes">'</span><span class="hl-string">val</span><span class="hl-quotes">'</span><span class="hl-default">: </span><span class="hl-quotes">'</span><span class="hl-string">Two</span><span class="hl-quotes">'</span><span class="hl-default">}</span></pre></div></div>
<p>These are the attributes for each child element stored in a dictionary. Being able to work with an XML element&#8217;s attributes as a Python dictionary is a great feature and fits well with the dynamic nature of XML attributes.</p>
<h2><a href="#WritingXML">Writing XML</a></h2>
<p>Now that we&#8217;ve tried our hand at reading XML, let&#8217;s try creating some. If you understand the reading process, you should have no trouble understanding the creation process because it works in much the same manner. What we are going to do in this example is recreate the XML data that we were working with above.</p>
<p>The first step is to create our <code><root></root></code> element:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#create the root &lt;root&gt;
</span><span class="hl-identifier">root_element</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">Element</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">root</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>After this code is executed, the variable <code>root_element</code> is an Element object, just like the Element objects that we used earlier to parse the XML.</p>
<p>The next step is to create the two child elements. There are two ways to do this.</p>
<p>In the first method, if you know exactly what you are creating, it&#8217;s easiest to use the <code>SubElement</code> method, which creates an Element object that is a subelement (or child) of another Element object:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#create the first child &lt;child&gt;One&lt;/child&gt;
</span><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">SubElement</span><span class="hl-brackets">(</span><span class="hl-identifier">root_element</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>This will create a <code><child></child></code> Element that is a child of <code>root_element</code>.  We then need to set the text associated with that element.  To do this we use the same text attribute that we used in the first parsing example. However, instead of simply reading the text attribute we set its value:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">One</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>The second approach to creating a child element is to create an Element object separately (rather than a sub element) and append it to a parent Element object.  The results are exactly the same - this is simply a different approach that may come in handy when creating your XML,or working with two sets of XML data.</p>
<p>First we create an Element object in the same way that we created the root element:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#create the second child &lt;child&gt;Two&lt;/child&gt;
</span><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">Element</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Two</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>This creates the <code>child</code> Element object and sets its text to &#8220;Two&#8221;.  We then append it to the root element: </p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#now append
</span><span class="hl-identifier">root_element</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">child</span><span class="hl-brackets">)</span></pre></div></div>
<p>Pretty simple!  Now, if we want to look at the contents of our <code>root_element</code> (or any other Element object for that matter) we can use the handy <code>tostring</code> function. It does exactly what it says that it does: it converts an Element object into a human readable string.</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Let's see the results
</span><span class="hl-reserved">print </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">tostring</span><span class="hl-brackets">(</span><span class="hl-identifier">root_element</span><span class="hl-brackets">)</span></pre></div></div>
<p><strong><a href="#Listing3">Listing 3</a></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">from </span><span class="hl-identifier">xml</span><span class="hl-default">.</span><span class="hl-identifier">etree </span><span class="hl-reserved">import </span><span class="hl-identifier">ElementTree as ET

</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-comment">#create the root &lt;/root&gt;&lt;root&gt;
	</span><span class="hl-identifier">root_element</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">Element</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">root</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-comment">#create the first child &lt;child&gt;One&lt;/child&gt;
	</span><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">SubElement</span><span class="hl-brackets">(</span><span class="hl-identifier">root_element</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">One</span><span class="hl-quotes">&quot;
	</span><span class="hl-comment">#create the second child &lt;child&gt;Two&lt;/child&gt;
	</span><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">Element</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Two</span><span class="hl-quotes">&quot;
	</span><span class="hl-comment">#now append
	</span><span class="hl-identifier">root_element</span><span class="hl-default">.</span><span class="hl-identifier">append</span><span class="hl-brackets">(</span><span class="hl-identifier">child</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Let's see the results
	</span><span class="hl-reserved">print </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">tostring</span><span class="hl-brackets">(</span><span class="hl-identifier">root_element</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>To recap, have a look at the code in Listing 3. When you run this code you will get the following output:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-default">&lt;/</span><span class="hl-identifier">root</span><span class="hl-default">&gt;&lt;</span><span class="hl-identifier">root</span><span class="hl-default">&gt;&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">One</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">Two</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;&lt;/</span><span class="hl-identifier">root</span><span class="hl-default">&gt;</span></pre></div></div>
<h2><a href="#WritingXMLAttributes">Writing XML Attributes</a></h2>
<p>If you want to create the XML with attributes (as illustrated in the second reading example), you can use the Element object&#8217;s <code>set</code> method.  To add the <code>val</code> attribute to the first element, use the following:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">set</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">val</span><span class="hl-quotes">&quot;</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">One</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>You may also set attributes when you create Element objects:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">Element</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-identifier">val</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">One</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<h2><a href="#ReadingXMLFiles">Reading XML Files</a></h2>
<p>Most of the time you won&#8217;t be working with XML data that you explicitly create in your code, instead you will usually read the XML data in from a data source, work with it, and then save it back out when you are done. Fortunately, configuring <em>ElementTree</em> to work with different data sources is very easy.  For example, let&#8217;s take the XML data that we first used and save it into a file named <code>our.xml</code> in the same location as our Python file.</p>
<p>There are a few methods that we can use to load XML data from a file. We are going to use the <code>parse</code> function. This function is nice because it will accept, as a parameter, the path to a file OR a &#8220;file-like&#8221; object.  The term &#8220;file-like&#8221; is used on purpose because the object does not have to be a file object per se - it simply has to be an object that behaves in a file-like manner. A &#8220;file-like&#8221; object is an object that implements a &#8220;file-like&#8221; interface, meaning that it shares many (if not all) methods with the file object. If an object is &#8220;file-like&#8221; this fact will usually be prominently mentioned in its documentation.</p>
<p>The first thing that we need in order to load the XML data is determine the full path to the <code>our.xml</code> file. In order to calculate this, we determine the full path of our Python source file, strip the filename from it, and then append <code>our.xml</code> to the path. This is rather simple given that the <code>__file__</code> attribute (available in Python 2.2 and later) is the relative path and filename of our Python source file. Although the <code>__file__</code> attribute will be a relative path, we can use it to calculate the absolute path using the standard <em>os</em> module:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">os</span></pre></div></div>
<p>We then call the <code>abspath</code> function to get the absolute path:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">abspath</span><span class="hl-brackets">(</span><span class="hl-identifier">__file__</span><span class="hl-brackets">)</span></pre></div></div>
<p>However, since we only want the directory name (not the full path and filename of our Python source file) we have to strip off the filename:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">dirname</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>Now that we have the directory in which the <code>our.xml</code> file resides, all we have to do is append the <code>our.xml</code> filename to the <code>xml_file</code> variable.  However, instead of just doing something like:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">xml_file</span><span class="hl-default"> += </span><span class="hl-quotes">&quot;</span><span class="hl-string">/our.xml</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>we will use the <em>os</em> module to join the two paths so that the resulting path is always correct regardless of what operating system our code is executed on:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">join</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">our.xml</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p><strong>Note</strong>: If you have any trouble understanding what any of the code used to determine the path of <code>our.xml</code> is doing, try printing out <code>xml_file</code> after each of the above lines and it should become clear.</p>
<p>We now have the full path to the <code>our.xml</code> file.  In order to load its XML data we simply pass the path to the <code>parse</code> function:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">tree</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">parse</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>We now have an ElementTree object instance that represents our XML file.</p>
<p>Since we are working with files, we should watch out for incorrect paths, I/O errors, or the parse function failing for any other reason.  If you wish to be extra careful, you can wrap the parse function in a try/except block in order to catch any exceptions that may be thrown:</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">tree</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">parse</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">sar</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">except Exception</span><span class="hl-default">, </span><span class="hl-identifier">inst</span><span class="hl-default">:
       </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Unexpected error opening %s: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-identifier">inst</span><span class="hl-brackets">)
       </span><span class="hl-reserved">return</span></pre></div></div>
<p>In the except block, I catch the Exception base class so that I catch any and all exceptions that may be thrown (in the case of a missing file it will most likely be an <code>IOError</code> exception).</p>
<h2><a href="#WritingXMLDatatoaFile">Writing XML Data to a File</a></h2>
<p>Now that we know how to read in XML data, we should look at how one writes XML data out to a file.  Let&#8217;s assume that after reading in the <code>out.xml</code> fiie we want to add another item to the XML file that we just read in:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">SubElement</span><span class="hl-brackets">(</span><span class="hl-identifier">tree</span><span class="hl-code">.</span><span class="hl-identifier">getroot</span><span class="hl-brackets">()</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Three</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>Notice that in order to add a child to the root element we used the ElementTree object&#8217;s <code>getroot</code> function. The <code>getroot</code> function simply returns the root Element object of the XML data.</p>
<p>Now that we have a third child element, let&#8217;s write the XML data back out to <code>our.xml</code>. Thanks to <em>ElementTree</em> this is a painless experience:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">tree</span><span class="hl-default">.</span><span class="hl-identifier">write</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>That&#8217;s it!</p>
<p>If we want to be really careful when writing the XML data out to a file, we&#8217;ll watch out for exceptions. However most of the time the <code>write</code> method will succeed without throwing an exception; it is more important to be sure that the path used is correct.  Often times, instead of getting the exception that you want, you end up with an XML file stored in some far off and strange location on your hard drive because your path was incorrect or you did not specify the full path.  But, as is often the case when programming, better safe than sorry:</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">tree</span><span class="hl-default">.</span><span class="hl-identifier">write</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
</span><span class="hl-reserved">except Exception</span><span class="hl-default">, </span><span class="hl-identifier">inst</span><span class="hl-default">:
       </span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Unexpected error writing to file %s: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-identifier">inst</span><span class="hl-brackets">)
       </span><span class="hl-reserved">return</span></pre></div></div>
<p>To recap you can find all of the code from this section in Listing 4.</p>
<p><strong><a href="#Listing4">Listing 4</a></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">from </span><span class="hl-identifier">xml</span><span class="hl-default">.</span><span class="hl-identifier">etree </span><span class="hl-reserved">import </span><span class="hl-identifier">ElementTree as ET
</span><span class="hl-reserved">import </span><span class="hl-identifier">os

</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">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">abspath</span><span class="hl-brackets">(</span><span class="hl-identifier">__file__</span><span class="hl-brackets">)
	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">dirname</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">join</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">our.xml</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">tree</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">parse</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
	</span><span class="hl-reserved">except Exception</span><span class="hl-default">, </span><span class="hl-identifier">inst</span><span class="hl-default">:
		</span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Unexpected error opening %s: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-identifier">inst</span><span class="hl-brackets">)
		</span><span class="hl-reserved">return

	</span><span class="hl-identifier">child</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">SubElement</span><span class="hl-brackets">(</span><span class="hl-identifier">tree</span><span class="hl-code">.</span><span class="hl-identifier">getroot</span><span class="hl-brackets">()</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">child</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">child</span><span class="hl-default">.</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Three</span><span class="hl-quotes">&quot;

	</span><span class="hl-reserved">try</span><span class="hl-default">:
		</span><span class="hl-identifier">tree</span><span class="hl-default">.</span><span class="hl-identifier">write</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
	</span><span class="hl-reserved">except Exception</span><span class="hl-default">, </span><span class="hl-identifier">inst</span><span class="hl-default">:
		</span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Unexpected error writing to file %s: %s</span><span class="hl-quotes">&quot;</span><span class="hl-default"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-identifier">inst</span><span class="hl-brackets">)
		</span><span class="hl-reserved">return

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>When you run the code and take a look at the <code>our.xml</code> file you should see that the the third child element has been added:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">&lt;</span><span class="hl-identifier">root</span><span class="hl-default">&gt;
&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">One</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;
&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">Two</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;
&lt;</span><span class="hl-identifier">child</span><span class="hl-default">&gt;</span><span class="hl-identifier">Three</span><span class="hl-default">&lt;/</span><span class="hl-identifier">child</span><span class="hl-default">&gt;
&lt;/</span><span class="hl-identifier">root</span><span class="hl-default">&gt;</span></pre></div></div>
<h2><a href="#ReadingfromtheWeb">Reading from the Web</a></h2>
<p>Working with a local file is very useful, but you might also be in a situation where you will have to work with an XML file that is located on the Internet, perhaps an RSS feed.  Fortunately, since the <code>parse</code> function explained above works with file-like elements, loading a URL is very easy.</p>
<p>First off, you need to import the <em>urllib</em> module; a standard module that allows you to open URLs in a method similar to opening local files:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">urllib</span></pre></div></div>
<p>In order to open a URL we use:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">feed</span><span class="hl-default"> = </span><span class="hl-identifier">urllib</span><span class="hl-default">.</span><span class="hl-identifier">urlopen</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">http://pythonmagazine.com/c/news/atom</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">tree</span><span class="hl-default"> = </span><span class="hl-identifier">ET</span><span class="hl-default">.</span><span class="hl-identifier">parse</span><span class="hl-brackets">(</span><span class="hl-identifier">feed</span><span class="hl-brackets">)</span></pre></div></div>
<h2><a href="#Conclusion">Conclusion</a></h2>
<p>And that&#8217;s that!  This concludes our brief introduction to XML parsing using the <em>ElementTree</em> module. Hopefully throughout this article you have seen how easy it is to create and manipulate XML using <em>ElementTree</em> &#8230;and I&#8217;ve only scratched the surface.  For more information take a look at the official Python documentation and some of the great examples on the effbot website. I&#8217;m sure you&#8217;ll be an XML wizard in no time.</p>
<p>[1] <a href="http://docs.python.org/whatsnew/modules.html#SECTION0001420000000000000000">http://docs.python.org/whatsnew/modules.html#SECTION0001420000000000000000</a><br />
[2] <a href="http://effbot.org/zone/pythondoc-elementtree-ElementTree.htm#elementtree.ElementTree.XML-function">http://effbot.org/zone/pythondoc-elementtree-ElementTree.htm#elementtree.ElementTree.XML-function</a><br />
[3] <a href="http://effbot.org/zone/pythondoc-elementtree-ElementTree.htm#elementtree.ElementTree.ElementTree-class">http://effbot.org/zone/pythondoc-elementtree-ElementTree.htm#elementtree.ElementTree.ElementTree-class</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2008/05/07/elegant-xml-parsing-using-the-elementtree-module/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
