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

<channel>
	<title>learning python</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>
	<lastBuildDate>Wed, 21 Sep 2011 03:08:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Quiet Lately</title>
		<link>http://www.learningpython.com/2011/09/16/quiet-lately/</link>
		<comments>http://www.learningpython.com/2011/09/16/quiet-lately/#comments</comments>
		<pubDate>Sat, 17 Sep 2011 02:58:22 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=228</guid>
		<description><![CDATA[Hey Everyone, or anyone that&#8217;s still around sorry it&#8217;s been so quiet around here lately, I&#8217;ve just had so much on my plate. Moving, baby, wife, work, a new homebrewing passion, reading, writing, and so on. All of this has led to very little time spent on this blog. I have some things in mind [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2011%2F09%2F16%2Fquiet-lately%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2011%2F09%2F16%2Fquiet-lately%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Hey Everyone, or anyone that&#8217;s still around sorry it&#8217;s been so quiet around here lately, I&#8217;ve just had so much on my plate. Moving, baby, wife, work, a new homebrewing passion, reading, writing, and so on. All of this has led to very little time spent on this blog.</p>
<p>I have some things in mind for this blog, but I never seem to get around to writing the posts or doing the work. Hopefully I&#8217;ll be able to get back into it soon.</p>
<p>At work we&#8217;ve delved into the <a href="http://www.android.com/">Android</a> platform and created an online app builder called <a href="http://andromo.com/">andromo</a>, which means I&#8217;ve been writing a lot of Java and hanging out on smart phones and tablets. If you are interested you can see some of the apps that have been built and added to the Android Market in our <a href="http://andromo.com/apps">showcase</a>.</p>
<p>You can keep up with what I&#8217;m doing on twitter: <a href="http://twitter.com/#!/MarkAtAndromo">@MarkAtAndromo</a> or add me to a circle on google+ under <a href="https://plus.google.com/109316912330545247098/">Mark Mruss</a> and yes I follow <a href="https://plus.google.com/115212051037621986145/">Guido</a>. If you are not on Google plus and need an invite let me know in the comments.</p>
<p>Oh and I also write on the <a href="http://blog.andromo.com">Andromo blog</a> from time to time as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2011/09/16/quiet-lately/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>New Belorussian/Belarusian Translation</title>
		<link>http://www.learningpython.com/2011/04/21/newbelorussian/</link>
		<comments>http://www.learningpython.com/2011/04/21/newbelorussian/#comments</comments>
		<pubDate>Thu, 21 Apr 2011 14:21:03 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[Translation]]></category>

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

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

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

		<guid isPermaLink="false">http://www.learningpython.com/?p=198</guid>
		<description><![CDATA[Hey Everyone, just an update on the last post. I was able to dig through the wordpress files and find where the hack was and it appears to be fixed now. Again if you notice anything strange happening here, redirects to external sites and whatnot, please let me know. Also, does anyone here use any [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F08%2F12%2Fhacking-fixed-and-python-on-the-web%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F08%2F12%2Fhacking-fixed-and-python-on-the-web%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Hey Everyone, just an update on the last post. I was able to dig through the wordpress files and find where the hack was and it appears to be fixed now. </p>
<p>Again if you notice anything strange happening here, redirects to external sites and whatnot, please let me know.</p>
<p>Also, does anyone here use any of the python web frameworks? I&#8217;d like to try my hand at them, but I&#8217;m having difficulty deciding between Pylons, Django, and Zope. I&#8217;m a total n00b when it comes to web programming, so it&#8217;s something that I&#8217;d like to be better at, so one of my requirements is being easy for beginners to learn.</p>
<p>If anyone has any thoughts or advice please post a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2010/08/12/hacking-fixed-and-python-on-the-web/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Possibly Hacked 2.0</title>
		<link>http://www.learningpython.com/2010/08/03/possibly-hacked-2-0/</link>
		<comments>http://www.learningpython.com/2010/08/03/possibly-hacked-2-0/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 03:52:17 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=196</guid>
		<description><![CDATA[Just to let everyone who still reads this blog that it looks as though I have been hacked again. Please don&#8217;t believe the rumours, I am not selling, nor will I ever, levitra online. If you notice anything strange in the text on this blog, or you end up redirected to some strange site, please [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F08%2F03%2Fpossibly-hacked-2-0%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F08%2F03%2Fpossibly-hacked-2-0%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Just to let everyone who still reads this blog that it looks as though I have been hacked again. </p>
<p>Please don&#8217;t believe the rumours, I am not selling, nor will I ever, levitra online.</p>
<p>If you notice anything strange in the text on this blog, or you end up redirected to some strange site, please let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2010/08/03/possibly-hacked-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing Descriptors and Properties</title>
		<link>http://www.learningpython.com/2010/04/25/introducing-descriptors-and-properties/</link>
		<comments>http://www.learningpython.com/2010/04/25/introducing-descriptors-and-properties/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 01:21:51 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[Python Magazine]]></category>
		<category><![CDATA[descriptors]]></category>
		<category><![CDATA[properties]]></category>

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

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

		<guid isPermaLink="false">http://www.learningpython.com/?p=169</guid>
		<description><![CDATA[Note: This article was first published the April 2008 issue of Python Magazine By: Mark Mruss GUI programming, like many other types of programming, can sometimes prove exhausting because you must repeat yourself over and over again. AVC is one tool available to Python GUI programmers that attempts to simplify things by synchronizing application data [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F03%2F14%2Favc-simplifying-your-gui-code%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2010%2F03%2F14%2Favc-simplifying-your-gui-code%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Note: This article was first published the <a href="http://www.pythonmagazine.com/c/issue/view/68">April 2008</a> issue of <a href="http://www.pythonmagazine.com/">Python Magazine</a></p>
<p><strong>By: Mark Mruss</strong></p>
<p>GUI programming, like many other types of programming, can sometimes prove exhausting because you must repeat yourself over and over again. <a href="http://avc.inrim.it/html/">AVC</a> is one tool available to Python GUI programmers that attempts to simplify things by synchronizing application data and GUI widgets.</p>
<h2>Introduction</h2>
<p>Every once in a while I find myself browsing the Internet trying to find out what&#8217;s new and exciting in the Python world. Sometimes I browse to find topics for this article; other times mere curiosity draws me across the web. While I was browsing the other day, I stumbled across <em>AVC: the Application View Controller</em> <a href="http://avc.inrim.it/html/">[1]</a>. I was immediately intrigued by it because itsÃ¢Â€Â™ name is so similar to the Model View Controller (MVC) pattern. Being familiar with the Model View Controller pattern, and admittedly having  struggles with it in the past, I decided to check out AVC to determine if it might be a viable alternative.</p>
<p>After reading about AVC I was intrigued for several reasons. The main reason was the promise of &#8220;a multiplatform, fully automatic, live connection among graphical interface widgets and application variables.&#8221; <a href="http://avc.inrim.it/html/">[2]</a> This means that graphical widgets can be connected to variables and automatically synchronized. One of the (many?) problems with Graphical User Interface (GUI) programming is that you often find yourself doing the same thing over and over again. One of the things that you end of doing over and over again is setting the contents of a widget based on the value of a variable, and then subsequently, setting that variable&#8217;s value based on the current state of the widget. Whenever someone promises me an automatic connection between GUI widgets and my variables, I&#8217;m interested.</p>
<p><span id="more-169"></span></p>
<p>The other reason for investigating AVC is my past struggles with the Model View Controller pattern. I like the decoupling that the MVC pattern seems to provide, but I often feel as though I am needlessly duplicating code in order to stick with the pattern.  I looked into AVC hoping to find a simple framework that will avoid this and guide the separation of my application data from my GUI logic. However in the end, I realized that AVC (in its current state), does not appear to achieve this across all widget toolkits. It does allow you to separate your application from much of the GUI logic that one would normally need, but it does not appear to allow you to fully separate the data from the GUI.</p>
<p>AVC is being developed by Fabrizio Pollastri, and is released under version 3 of the GPL. I was unable to find much information about the projectÃ¢Â€Â™s future or design objectives. But judging by the release notes, it is still being actively developed.  The project is only at version 0.5 so donÃ¢Â€Â™t be surprised if the API (Application Programming Interface) or some of the goals change.  Although relatively new, AVC bears further investigation because it already simplifies your GUI programming and contains the potential to do much more.  In this article, I will introduce some of the main concepts behind AVC, and provide a small, working example using AVC and PyGTK.</p>
<h2>Installing AVC</h2>
<p>AVC is a &#8220;Python module written in pure python&#8221; <a href="http://avc.inrim.it/html/">[3]</a>. This means that AVC is easy to install and does not have any dependencies aside from Python 2.2 or greater. You can download the current version (0.5.0) from the website or, if you are a lucky Linux user like me, you can install via your handy package manger.  If you download the source, you can install it after extraction, using the following command:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">python setup</span><span class="hl-default">.</span><span class="hl-identifier">py install</span></pre></div></div>
<p>Depending on which widget toolkit you plan on using, the following requirements must also be met:</p>
<ul>
<li><strong>GTK+:</strong> PyGTK 2.8 &#8211; 2.10</li>
<li><strong>Qt:</strong> PyQt or PyQt4v3 &#8211; v4</li>
<li><strong>Tk:</strong> Tkinter 2.4</li>
<li><strong>wxWidgets:</strong> wxPython 2.6</li>
</ul>
<p>You can easily install any of the above toolkits using your favourite package manager, a source archive, or a binary installer found on each toolkitÃ¢Â€Â™s main website. Once AVC is installed, you can test the installation by importing the <code>avc</code> module from the interactive interpreter. If all goes well you will see something similar to the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-default">$ </span><span class="hl-identifier">python
Python </span><span class="hl-number">2.4.4 </span><span class="hl-brackets">(</span><span class="hl-comment">#2, Jan  3 2008, 13:36:28)
</span><span class="hl-brackets">[</span><span class="hl-identifier">GCC </span><span class="hl-number">4.2.3 20071123 </span><span class="hl-brackets">(</span><span class="hl-identifier">prerelease</span><span class="hl-brackets">) (</span><span class="hl-identifier">Debian </span><span class="hl-number">4.2.2</span><span class="hl-code">-</span><span class="hl-number">4</span><span class="hl-brackets">)] </span><span class="hl-identifier">on linux2
Type </span><span class="hl-quotes">&quot;</span><span class="hl-string">help</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">copyright</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">credits</span><span class="hl-quotes">&quot; </span><span class="hl-reserved">or </span><span class="hl-quotes">&quot;</span><span class="hl-string">license</span><span class="hl-quotes">&quot; </span><span class="hl-reserved">for </span><span class="hl-identifier">more information</span><span class="hl-code">.
&gt;&gt;&gt; </span><span class="hl-reserved">import </span><span class="hl-identifier">avc</span><span class="hl-code">
&gt;&gt;&gt;</span></pre></div></div>
<h2>Widget Support</h2>
<p>In its current state, AVC does not support all widgets available across all toolkits. It does currently support the following widgets:</p>
<ul>
<li>Button</li>
<li>Check Box</li>
<li>Combo Box (Not supported in Tk)</li>
<li>Entry</li>
<li>Label</li>
<li>Radio Button</li>
<li>Slider</li>
<li>Spin Button</li>
<li>Status Bar (Only supported by GTK+ and wxWidgets)</li>
<li>Text View</li>
<li>Toggle Button.</li>
</ul>
<p>The support of each of these widget types is then handled by specific widgets in each toolkit.</p>
<h2>Name-Matching</h2>
<p>In order to automatically synchronize variables and GUI widgets, AVC uses a name-matching technique. AVC supports two methods of name matching. The first method requires that the variable and the widget have the same name. For example, if you have a variable named <code>my_data</code> it will match with a widget also named <code>my_data</code>. In other words, if a variable and a widget have the same name they will be connected and their values synchronized.</p>
<p>The second name-matching technique allows you to connect variables to one or more widgets. Widgets can only be connected to one variable, but variables can be connected to any number of widgets. Using the second name-matching technique, you have a match if the widget name contains a double-underscore (<code>__</code>), <strong>and</strong> the portion before the double-underscore matches the variable name. For example, if you have variable named <code>my_numeric_value</code> and you want to match it with a Label widget and an Entry widget, you do this by naming the widgets as follows:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">my_numeric_value__label
my_numeric_value__entry</span></pre></div></div>
<p>Again, the text before the &#8220;__&#8221; must match the variable name, and the text after the &#8220;__&#8221; can be whatever you want to differentiate your widgets or ensure uniqueness (if the toolkit requires it).</p>
<h2>A GTK+, PyGTK, and AVC Example</h2>
<p>For this AVC example, I will use the GTK+ widget toolkit and PyGTK. PyGTK a &#8220;is a set of bindings to the GTK+ user interface toolkit for the Python language&#8221; <a href="http://faq.pygtk.org/index.py?req=all#1.1">[4]</a>. This means that it lets us write GUI applications in Python using the GTK+ widget toolkit. To avoid any flame wars: I did not choose GTK+ because it is the best toolkit but because it is the toolkit with which I am the most familiar.  In order to run this example you will need to have PyGTK 2.8 or later installed. You can get the latest version of PyGTK from the PyGTK website. <a href="http://www.pygtk.org/downloads.html">[5]</a></p>
<p>As I mentioned earlier, AVC works with many different widgets types. It also has many different features. I won&#8217;t be covering all of the features or widgets types in this column; if you are interesting in learning about some of these features or how to work with different widgets types, please see the AVC documentation. <a href="http://avc.inrim.it/doc/user_manual.pdf">[6]</a></p>
<p>This example is relatively simple, but it should illustrate some of the basic features of AVC. The example application asks for a personÃ¢Â€Â™s name and then displays that name in pop-up dialog. It will have the following features:</p>
<ol>
<li>A <code>gtk.TextView</code> widget to display the person&#8217;s name and allow the name to be edited. The <code>gtk.TextView</code> widget will be synchronised with a variable.</li>
<li>A <code>gtkButton</code> that will pop-up a <code>gtk.MessageDialog</code> to show the person&#8217;s name.</li>
<li>A <code>gtk.Button</code> that will reset the name to the name with which the application was initialized.</li>
</ol>
<p>To begin we need to import all of the modules necessary:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">gtk
</span><span class="hl-reserved">import </span><span class="hl-identifier">avc</span><span class="hl-default">.</span><span class="hl-identifier">avcgtk</span></pre></div></div>
<p><strong>Note</strong>: I am using a <code>gtk.TextView</code> widget instead of a <code>gtk.Entry</code> widget. In its current state, AVC does not propagate changes in <code>gtk.Entry</code> widgets back to the connected variable. I&#8217;m not sure if this is a current limitation or part of the design.</p>
<p>The above code imports the PyGTK module necessary to work with GTK+. It also imports the <code>avcgtk</code> module, which is used to link our &#8220;application variables&#8221; with our GTK+ GUI. Depending on what widget toolkit you use, you will have to use different modules. For example, if you are working with Qt4, you will import:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">avc</span><span class="hl-default">.</span><span class="hl-identifier">avcqt4</span></pre></div></div>
<p>The next step is to create the &#8220;application&#8221; class. This will be the class that contains the data. In this example it will also create the GUI:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">gtkAVC</span><span class="hl-brackets">(</span><span class="hl-identifier">avc</span><span class="hl-code">.</span><span class="hl-identifier">avcgtk</span><span class="hl-code">.</span><span class="hl-identifier">AVC</span><span class="hl-brackets">)</span><span class="hl-default">:</span></pre></div></div>
<p>Notice that we derive our application from the <code>avcgtk</code> module&#8217;s AVC class. This is the GTK+ specific AVC class with which we will work. We will also create an <code>__init__</code> method in the <code>gtkAVC</code> class. This is where we will initialize the data that will be connected to the GUI and create the GUI via the <code>init_gui</code> method:</p>
<div class="hl-surround" ><div class="hl-main"><pre><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-quotes">&quot;&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-comment">#set the variable and save the initial name
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">initial_name</span><span class="hl-default"> = </span><span class="hl-identifier">name
    self</span><span class="hl-default">.</span><span class="hl-identifier">name</span><span class="hl-default"> = </span><span class="hl-identifier">name
    </span><span class="hl-comment">#setup GUI
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">init_gui</span><span class="hl-brackets">()</span></pre></div></div>
<p>What we have here is pretty simple. We have the optional parameter <code>name</code> that we store as the current name and as the initial name. We then call the <code>init_gui</code> method that will create the GUI. The contents of the <code>init_gui</code> method can be seen in Listing 1. I won&#8217;t explain most of this code since the majority of it is PyGTK specific. However I will make note of several relevant segments below.</p>
<p><strong>Listing 1</strong></p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">init_gui</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">#Setup the window and the layout manager
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Window</span><span class="hl-brackets">()
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">destroy</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">main_quit</span><span class="hl-brackets">)

    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">HBox</span><span class="hl-brackets">()
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">h_layout</span><span class="hl-brackets">)

    </span><span class="hl-comment">#create the widgets
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_label</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Label</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">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">text_label</span><span class="hl-brackets">)

    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">frame</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Frame</span><span class="hl-brackets">()
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">frame</span><span class="hl-brackets">)
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">scrolled_window</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">ScrolledWindow</span><span class="hl-brackets">()
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">frame</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">scrolled_window</span><span class="hl-brackets">)

    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_view</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">TextView</span><span class="hl-brackets">()
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_view</span><span class="hl-default">.</span><span class="hl-identifier">set_name</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">name__text_view</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">scrolled_window</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">text_view</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">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Button</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">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_button</span><span class="hl-default">.</span><span class="hl-identifier">connect</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-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-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-brackets">)

    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">reset_button</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Button</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Reset</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">reset_button</span><span class="hl-default">.</span><span class="hl-identifier">connect</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-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">on_reset_clicked</span><span class="hl-brackets">)
    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">reset_button</span><span class="hl-brackets">)

    </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default">.</span><span class="hl-identifier">show_all</span><span class="hl-brackets">()</span></pre></div></div>
<p>The only AVC specific code segment in the <code>init_gui</code> function is where we set the name of the <code>gtk.TextView</code> widget:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_view</span><span class="hl-default">.</span><span class="hl-identifier">set_name</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">name__text_view</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>This is all the code that we need to connect the <code>gtk.TextView</code> widget with the <code>name</code> variable that we created at the beginning of the <code>__init__</code> function. (Now, how&#8217;s that for simple?) Notice that the <code>name</code> section of the &#8220;name__text_view&#8221; string will match with the <code>self.name</code> variable. It is also important to note that the variable and the widget are not yet connected. They will become connected when the <code>avc_init</code> method is called.</p>
<p>The other non-AVC related code of note is the connection of both <code>gtk.Button</code> widgetsÃ¢Â€Â™ clicked signals with signal handlers. We connect the &#8220;hello&#8221; button to the <code>on_hello_clicked</code> method and the &#8220;reset&#8221; button to the <code>on_reset_clicked</code> method.</p>
<p>That&#8217;s it for the <code>init_gui</code> function, now let&#8217;s look at the two signal handlers. The <code>on_hello_clicked</code> method, shown in Listing 2, simply displays the name in a <code>gtk.MessageDialog</code>. What should be interesting to GUI programmers about this function is that instead of reading the data from the <code>gtk.TextView</code> widget, we simply reference <code>self.name</code> for the dialog&#8217;s text. We can do this because <code>self.name</code> and the <code>gtk.TextView</code> widget are connected and their values are always the same.</p>
<p><strong>Listing 2</strong></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-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-reserved">def </span><span class="hl-identifier">close</span><span class="hl-brackets">(</span><span class="hl-identifier">dialog</span><span class="hl-code">, </span><span class="hl-identifier">response</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-comment">#Close the dialog on ok
        </span><span class="hl-identifier">dialog</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()
    </span><span class="hl-identifier">message_dlg</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">MessageDialog</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">window</span><span class="hl-code">
        , </span><span class="hl-number">0</span><span class="hl-code">
        , </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">MESSAGE_INFO</span><span class="hl-code">
        , </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">BUTTONS_OK</span><span class="hl-code">
        , </span><span class="hl-brackets">(</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">name</span><span class="hl-brackets">))
    </span><span class="hl-identifier">message_dlg</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">response</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-identifier">close</span><span class="hl-brackets">)
    </span><span class="hl-identifier">message_dlg</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()</span></pre></div></div>
<p>The <code>on_reset_clicked</code> function is also very simple and straightforward. We simply reset the name to the initial name:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_reset_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-comment">#Reset the name to the initial name
    </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">self</span><span class="hl-default">.</span><span class="hl-identifier">initial_name</span></pre></div></div>
<p>Again, notice that we don&#8217;t have to worry about doing anything to the <code>gtk.TextView</code> widget that displays the current name. By simply modifying the data, what is displayed in the GUI will automatically be updated by AVC.</p>
<p>The next and final step in our test application is to create our class instances and actually show the GUI:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">__name__</span><span class="hl-code"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">gtk_avc</span><span class="hl-default"> = </span><span class="hl-identifier">gtkAVC</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-brackets">)
    </span><span class="hl-identifier">gtk_avc</span><span class="hl-default">.</span><span class="hl-identifier">avc_init</span><span class="hl-brackets">()
    </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>Since I am working in a Python file, I perform a simple test to make sure that the file is being launched directly instead of being imported as a module. I then create an instance of the <code>gtkAVC</code> class setting the name to be my name. The <code>avc_init</code> method is then called (which is a member of the <code>avc.avcgtk.AVC</code> class). The <code>avc_init</code> method is where all of the magic happens.  It is where AVC goes through an application&#8217;s variables and connects them to the GUI widgets based upon the name matching technique explained earlier. <code>avc_init</code> must be called <strong>after</strong> all of the data in the &#8220;application&#8221; and the widgets have been created.</p>
<p>The final step in this example, is to run the <code>gtk.main</code> function. This is the &#8220;main loop&#8221; of our PyGTK based application and is standard when working with PyGTK.</p>
<p>The entire code can be seen in Listing 3. When you run the code you will be greeted with something similar to Figure 1. It may not seem like much, but what we have here is a fully functional AVC &#8220;application&#8221;. This simple &#8220;application&#8221; illustrates how easy it is to create an automatic connection between your data and your GUI.</p>
<div id="attachment_172" class="wp-caption alignnone" style="width: 310px"><img src="http://www.learningpython.com/wp-content/uploads/2010/03/Figure1-300x230.png" alt="Figure1" title="Figure1" width="300" height="230" class="size-medium wp-image-172" /><p class="wp-caption-text">Figure1</p></div>
<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">gtk
</span><span class="hl-reserved">import </span><span class="hl-identifier">avc</span><span class="hl-default">.</span><span class="hl-identifier">avcgtk

</span><span class="hl-reserved">class </span><span class="hl-identifier">gtkAVC</span><span class="hl-brackets">(</span><span class="hl-identifier">avc</span><span class="hl-code">.</span><span class="hl-identifier">avcgtk</span><span class="hl-code">.</span><span class="hl-identifier">AVC</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-quotes">&quot;&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-comment">#set the variable and save the initial name
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">initial_name</span><span class="hl-default"> = </span><span class="hl-identifier">name
        self</span><span class="hl-default">.</span><span class="hl-identifier">name</span><span class="hl-default"> = </span><span class="hl-identifier">name
        </span><span class="hl-comment">#setup GUI
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">init_gui</span><span class="hl-brackets">()

    </span><span class="hl-reserved">def </span><span class="hl-identifier">init_gui</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">#Setup the window and the layout manager
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Window</span><span class="hl-brackets">()
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">destroy</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">main_quit</span><span class="hl-brackets">)

        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">HBox</span><span class="hl-brackets">()
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">h_layout</span><span class="hl-brackets">)

        </span><span class="hl-comment">#create the widgets
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_label</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Label</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">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">text_label</span><span class="hl-brackets">)

        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">frame</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Frame</span><span class="hl-brackets">()
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">frame</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">scrolled_window</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">ScrolledWindow</span><span class="hl-brackets">()
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">frame</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">scrolled_window</span><span class="hl-brackets">)

        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_view</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">TextView</span><span class="hl-brackets">()
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">text_view</span><span class="hl-default">.</span><span class="hl-identifier">set_name</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">name__text_view</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">scrolled_window</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">text_view</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">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Button</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">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_button</span><span class="hl-default">.</span><span class="hl-identifier">connect</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-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-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">hello_button</span><span class="hl-brackets">)

        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">reset_button</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">Button</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Reset</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">reset_button</span><span class="hl-default">.</span><span class="hl-identifier">connect</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-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">on_reset_clicked</span><span class="hl-brackets">)
        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">h_layout</span><span class="hl-default">.</span><span class="hl-identifier">add</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">reset_button</span><span class="hl-brackets">)

        </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">window</span><span class="hl-default">.</span><span class="hl-identifier">show_all</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-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-reserved">def </span><span class="hl-identifier">close</span><span class="hl-brackets">(</span><span class="hl-identifier">dialog</span><span class="hl-code">, </span><span class="hl-identifier">response</span><span class="hl-brackets">)</span><span class="hl-default">:
            </span><span class="hl-comment">#Close the dialog on ok
            </span><span class="hl-identifier">dialog</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()
        </span><span class="hl-identifier">message_dlg</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">MessageDialog</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">window</span><span class="hl-code">
            , </span><span class="hl-number">0</span><span class="hl-code">
            , </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">MESSAGE_INFO</span><span class="hl-code">
            , </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">BUTTONS_OK</span><span class="hl-code">
            , </span><span class="hl-brackets">(</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">name</span><span class="hl-brackets">))
        </span><span class="hl-identifier">message_dlg</span><span class="hl-default">.</span><span class="hl-identifier">connect</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">response</span><span class="hl-quotes">&quot;</span><span class="hl-code">, </span><span class="hl-identifier">close</span><span class="hl-brackets">)
        </span><span class="hl-identifier">message_dlg</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()

    </span><span class="hl-reserved">def </span><span class="hl-identifier">on_reset_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
        </span><span class="hl-comment">#Reset the name to the initial name
        </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">self</span><span class="hl-default">.</span><span class="hl-identifier">initial_name

if </span><span class="hl-brackets">(</span><span class="hl-identifier">__name__</span><span class="hl-code"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
    </span><span class="hl-identifier">gtk_avc</span><span class="hl-default"> = </span><span class="hl-identifier">gtkAVC</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-brackets">)
    </span><span class="hl-identifier">gtk_avc</span><span class="hl-default">.</span><span class="hl-identifier">avc_init</span><span class="hl-brackets">()
    </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<h2>Benefits and Limitations</h2>
<p>For a project that is little more than one year old (the first release was in January 2007) AVC appears quite stable and ready to be used. This is not to say that AVC is perfect. I did encounter a few issues.</p>
<p>The most notable issue that I encountered is the tightly coupled structure that AVC seems to impose on your application. For a module that tries to simplify the relationship between application data and GUI&#8217;s, this feels like a bit of an issue because. For example, when testing using PyGTK I was able to easily separate the GUI and the &#8220;application&#8221; into separate classes. But when I tried to do the same thing using PyQt4, I encountered an error because the <code>avc_timer</code> function in the <code>avc.avcqt4.AVC</code> module expects that the &#8220;application&#8221; class is itself a <code>QObject</code> (namely the actual <code>QApplication</code>). I find this counterintuitive since being able to separate the data from the GUI-logic seems to be a goal of AVC and similar tools. If you are able to separate the &#8220;application&#8221; fully from the GUI, you can easily connect your &#8220;application&#8221; to different GUI&#8217;s, and (by changing the AVC base class) even different widget toolkits.</p>
<p>I would also be interested in the ability to connect more types of data to more types of widgets. For example, I am interested in synchronizing Python lists with the contents of List boxes and Combo boxes. This is in addition to the current ability to synchronize the selection in the two widgets with integers.</p>
<p>Of course AVC also has a lot going for it. For one, I really like that AVC works with different widget toolkits. I have not seen this very often. It is a real benefit, especially when it comes to people adopting AVC. Hopefully in the future AVC will allow for further separation of the data and the GUI, truly enabling us to use different GUI&#8217;s and different widget toolkits with our data.</p>
<p>What I like most about AVC is its simplicity. I have played around with similar solutions and AVC is one of the leaders in terms of ease of use. I was able to get create a simple AVC based application in almost no time at all. (The time that it did take was spent trying to remember PyGTK.) Much of this has to do with the streamlined nature of AVC. There is very little to configure regardless of what widget toolkit you use. While this simplicity limits what AVC can currently achieve compared to other solutions, it also makes the barrier to entry low and the usage trivial. User friendliness is certainly a good thing in a package that aims to make GUI application development easier.</p>
<h2>Conclusion</h2>
<p>While the data that we worked with in the earlier example wasn&#8217;t that complicated (a simple string), I hope that it illustrates how helpful AVC is if you are working with a large amount of data or data that could be updated by an external source. Instead of having to worry about what widgets or toolkits the data was being displayed in, AVC lets us work with the data and GUI transparently, leaving the synchronization to AVC.</p>
<p>If what AVC offers sounds interesting to you, download it from the AVC website and try it out.  Although it it&#8217;s not there just yet with enough attention, usage, and contributions from the Python community, AVC should reach full-feature status in no time.</p>
<p><a href="http://avc.inrim.it/html/">[1] http://avc.inrim.it/html/</a><br />
<a href="http://avc.inrim.it/html/">[2] http://avc.inrim.it/html/</a><br />
<a href="http://avc.inrim.it/html/">[3] http://avc.inrim.it/html/</a><br />
<a href="http://faq.pygtk.org/index.py?req=all#1.1">[4] http://faq.pygtk.org/index.py?req=all#1.1</a><br />
<a href="http://www.pygtk.org/downloads.html">[5] http://www.pygtk.org/downloads.html</a><br />
<a href="http://avc.inrim.it/doc/user_manual.pdf">[6] http://avc.inrim.it/doc/user_manual.pdf</a></p>
<p><strong>Note:</strong> If you haven&#8217;t already, please check out my <a href="http://www.learningpython.com/2010/03/04/poll-python-version/">Python version poll</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2010/03/14/avc-simplifying-your-gui-code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Poll: Python Version</title>
		<link>http://www.learningpython.com/2010/03/04/poll-python-version/</link>
		<comments>http://www.learningpython.com/2010/03/04/poll-python-version/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 03:52:10 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[Poll]]></category>
		<category><![CDATA[python]]></category>

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

