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

<channel>
	<title>learning python &#187; PythonMagazine</title>
	<atom:link href="http://www.learningpython.com/tag/pythonmagazine/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.learningpython.com</link>
	<description>one man's journey into python...</description>
	<lastBuildDate>Mon, 26 Apr 2010 01:21:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Introducing Docstrings</title>
		<link>http://www.learningpython.com/2010/01/08/introducing-docstrings/</link>
		<comments>http://www.learningpython.com/2010/01/08/introducing-docstrings/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 03:41:06 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[Python Magazine]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[docstrings]]></category>
		<category><![CDATA[PythonMagazine]]></category>

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

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

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