remove redundant files

This commit is contained in:
rasbt 2016-01-27 22:54:10 -05:00
parent 360fd6be32
commit 3fc278cae3
4 changed files with 0 additions and 5362 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,416 +0,0 @@
[Sebastian Raschka](http://sebastianraschka.com)
last updated: 05/24/2014
<br>
**This is a subsection of ["A collection of not-so-obvious Python stuff you should know!"](http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/not_so_obvious_python_stuff.ipynb?create=1)**
<a id='sections'></a>
<br>
## Key differences between Python 2 and 3
<br>
There are some good articles already that are summarizing the differences between Python 2 and 3, e.g.,
- [https://wiki.python.org/moin/Python2orPython3](https://wiki.python.org/moin/Python2orPython3)
- [https://docs.python.org/3.0/whatsnew/3.0.html](https://docs.python.org/3.0/whatsnew/3.0.html)
- [http://python3porting.com/differences.html](http://python3porting.com/differences.html)
- [https://docs.python.org/3/howto/pyporting.html](https://docs.python.org/3/howto/pyporting.html)
etc.
But it might be still worthwhile, especially for Python newcomers, to take a look at some of those!
(Note: the the code was executed in Python 3.4.0 and Python 2.7.5 and copied from interactive shell sessions.)
<a id='py23_overview'></a>
<br>
### Overview - Key differences between Python 2 and 3
- [Unicode](#unicode)
- [The print statement](#print)
- [Integer division](#integer_div)
- [xrange()](#xrange)
- [Raising exceptions](#raising_exceptions)
- [Handling exceptions](#handling_exceptions)
- [next() function and .next() method](#next_next)
- [Loop variables and leaking into the global scope](#loop_leak)
- [Comparing unorderable types](#compare_unorder)
<br>
<br>
<a id='unicode'></a>
<br>
<br>
### Unicode...
[[back to Python 2.x vs 3.x overview](#py23_overview)]
####- Python 2:
We have ASCII `str()` types, separate `unicode()`, but no `byte` type
####- Python 3:
Now, we finally have Unicode (utf-8) `str`ings, and 2 byte classes: `byte` and `bytearray`s
<br>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">#############</span>
<span style="color: #888888"># Python 2</span>
<span style="color: #888888">#############</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">type</span>(unicode(<span style="background-color: #fff0f0">&#39;is like a python3 str()&#39;</span>))
<span style="color: #333333">&lt;</span><span style="color: #007020">type</span> <span style="background-color: #fff0f0">&#39;unicode&#39;</span><span style="color: #333333">&gt;</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">type</span>(b<span style="background-color: #fff0f0">&#39;byte type does not exist&#39;</span>)
<span style="color: #333333">&lt;</span><span style="color: #007020">type</span> <span style="background-color: #fff0f0">&#39;str&#39;</span><span style="color: #333333">&gt;</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="background-color: #fff0f0">&#39;they are really&#39;</span> <span style="color: #333333">+</span> b<span style="background-color: #fff0f0">&#39; the same&#39;</span>
<span style="background-color: #fff0f0">&#39;they are really the same&#39;</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">type</span>(<span style="color: #007020">bytearray</span>(b<span style="background-color: #fff0f0">&#39;bytearray oddly does exist though&#39;</span>))
<span style="color: #333333">&lt;</span><span style="color: #007020">type</span> <span style="background-color: #fff0f0">&#39;bytearray&#39;</span><span style="color: #333333">&gt;</span>
<span style="color: #888888">#############</span>
<span style="color: #888888"># Python 3</span>
<span style="color: #888888">#############</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;strings are now utf-8 </span><span style="color: #666666; font-weight: bold; background-color: #fff0f0">\u03BC</span><span style="background-color: #fff0f0">nico</span><span style="color: #666666; font-weight: bold; background-color: #fff0f0">\u0394</span><span style="background-color: #fff0f0">é!&#39;</span>)
strings are now utf<span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">8</span> μnicoΔé<span style="color: #FF0000; background-color: #FFAAAA">!</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">type</span>(b<span style="background-color: #fff0f0">&#39; and we have byte types for storing data&#39;</span>)
<span style="color: #333333">&lt;</span><span style="color: #008800; font-weight: bold">class</span> <span style="color: #FF0000; background-color: #FFAAAA">&#39;</span><span style="color: #BB0066; font-weight: bold">bytes</span><span style="background-color: #fff0f0">&#39;&gt;</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">type</span>(<span style="color: #007020">bytearray</span>(b<span style="background-color: #fff0f0">&#39;but also bytearrays for those who prefer them over strings&#39;</span>))
<span style="color: #333333">&lt;</span><span style="color: #008800; font-weight: bold">class</span> <span style="color: #FF0000; background-color: #FFAAAA">&#39;</span><span style="color: #BB0066; font-weight: bold">bytearray</span><span style="background-color: #fff0f0">&#39;&gt;</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="background-color: #fff0f0">&#39;string&#39;</span> <span style="color: #333333">+</span> b<span style="background-color: #fff0f0">&#39;bytes for data&#39;</span>
Traceback (most recent call last):s
File <span style="background-color: #fff0f0">&quot;&lt;stdin&gt;&quot;</span>, line <span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333">&lt;</span>module<span style="color: #333333">&gt;</span>
<span style="color: #FF0000; font-weight: bold">TypeError</span>: Can<span style="background-color: #fff0f0">&#39;t convert &#39;</span><span style="color: #007020">bytes</span><span style="background-color: #fff0f0">&#39; object to str implicitly</span>
</pre></div>
<a id='print'></a>
<br>
<br>
### The print statement
[[back to Python 2.x vs 3.x overview](#py23_overview)]
Very trivial, but this change makes sense, Python 3 now only accepts `print`s with proper parentheses - just like the other function calls ...
<br>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">print</span> <span style="background-color: #fff0f0">&#39;Hello, World!&#39;</span>
Hello, World<span style="color: #FF0000; background-color: #FFAAAA">!</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;Hello, World!&#39;</span>)
Hello, World<span style="color: #FF0000; background-color: #FFAAAA">!</span>
<span style="color: #888888"># Python 3</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;Hello, World!&#39;</span>)
Hello, World<span style="color: #FF0000; background-color: #FFAAAA">!</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">print</span> <span style="background-color: #fff0f0">&#39;Hello, World!&#39;</span>
File <span style="background-color: #fff0f0">&quot;&lt;stdin&gt;&quot;</span>, line <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #007020">print</span> <span style="background-color: #fff0f0">&#39;Hello, World!&#39;</span>
<span style="color: #333333">^</span>
<span style="color: #FF0000; font-weight: bold">SyntaxError</span>: invalid syntax
</pre></div>
<br>
And if we want to print the output of 2 consecutive print functions on the same line, you would use a comma in Python 2, and a `end=""` in Python 3:
<br>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">print</span> <span style="background-color: #fff0f0">&quot;line 1&quot;</span>, ; <span style="color: #007020">print</span> <span style="background-color: #fff0f0">&#39;same line&#39;</span>
line <span style="color: #0000DD; font-weight: bold">1</span> same line
<span style="color: #888888"># Python 3</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&quot;line 1&quot;</span>, end<span style="color: #333333">=</span><span style="background-color: #fff0f0">&quot;&quot;</span>) ; <span style="color: #007020">print</span> (<span style="background-color: #fff0f0">&quot; same line&quot;</span>)
line <span style="color: #0000DD; font-weight: bold">1</span> same line
</pre></div>
<a id='integer_div'></a>
<br>
<br>
### Integer division
[[back to Python 2.x vs 3.x overview](#py23_overview)]
This is a pretty dangerous thing if you are porting code, or executing Python 3 code in Python 2 since the change in integer-division behavior can often go unnoticed.
So, I still tend to use a `float(3)/2` or `3/2.0` instead of a `3/2` in my Python 3 scripts to save the Python 2 guys some trouble ... (PS: and vice versa, you can `from __future__ import division` in your Python 2 scripts).
<br>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">/</span> <span style="color: #0000DD; font-weight: bold">2</span>
<span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">//</span> <span style="color: #0000DD; font-weight: bold">2</span>
<span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">/</span> <span style="color: #6600EE; font-weight: bold">2.0</span>
<span style="color: #6600EE; font-weight: bold">1.5</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">//</span> <span style="color: #6600EE; font-weight: bold">2.0</span>
<span style="color: #6600EE; font-weight: bold">1.0</span>
<span style="color: #888888"># Python 3</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">/</span> <span style="color: #0000DD; font-weight: bold">2</span>
<span style="color: #6600EE; font-weight: bold">1.5</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">//</span> <span style="color: #0000DD; font-weight: bold">2</span>
<span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">/</span> <span style="color: #6600EE; font-weight: bold">2.0</span>
<span style="color: #6600EE; font-weight: bold">1.5</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #333333">//</span> <span style="color: #6600EE; font-weight: bold">2.0</span>
<span style="color: #6600EE; font-weight: bold">1.0</span>
</pre></div>
<a id='xrange'></a>
<br>
<br>
###`xrange()`
[[back to Python 2.x vs 3.x overview](#py23_overview)]
`xrange()` was pretty popular in Python 2.x if you wanted to create an iterable object. The behavior was quite similar to a generator ('lazy evaluation'), but you could iterate over it infinitely. The advantage was that it was generally faster than `range()` (e.g., in a for-loop) - not if you had to iterate over the list multiple times, since the generation happens every time from scratch!
In Python 3, the `range()` was implemented like the `xrange()` function so that a dedicated `xrange()` function does not exist anymore.
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
<span style="color: #333333">&gt;</span> python <span style="color: #333333">-</span>m timeit <span style="background-color: #fff0f0">&#39;for i in range(1000000):&#39;</span> <span style="background-color: #fff0f0">&#39; pass&#39;</span>
<span style="color: #0000DD; font-weight: bold">10</span> loops, best of <span style="color: #0000DD; font-weight: bold">3</span>: <span style="color: #0000DD; font-weight: bold">66</span> msec per loop
<span style="color: #333333">&gt;</span> python <span style="color: #333333">-</span>m timeit <span style="background-color: #fff0f0">&#39;for i in xrange(1000000):&#39;</span> <span style="background-color: #fff0f0">&#39; pass&#39;</span>
<span style="color: #0000DD; font-weight: bold">10</span> loops, best of <span style="color: #0000DD; font-weight: bold">3</span>: <span style="color: #6600EE; font-weight: bold">27.8</span> msec per loop
<span style="color: #888888"># Python 3</span>
<span style="color: #333333">&gt;</span> python3 <span style="color: #333333">-</span>m timeit <span style="background-color: #fff0f0">&#39;for i in range(1000000):&#39;</span> <span style="background-color: #fff0f0">&#39; pass&#39;</span>
<span style="color: #0000DD; font-weight: bold">10</span> loops, best of <span style="color: #0000DD; font-weight: bold">3</span>: <span style="color: #6600EE; font-weight: bold">51.1</span> msec per loop
<span style="color: #333333">&gt;</span> python3 <span style="color: #333333">-</span>m timeit <span style="background-color: #fff0f0">&#39;for i in xrange(1000000):&#39;</span> <span style="background-color: #fff0f0">&#39; pass&#39;</span>
Traceback (most recent call last):
File <span style="background-color: #fff0f0">&quot;/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/timeit.py&quot;</span>, line <span style="color: #0000DD; font-weight: bold">292</span>, <span style="color: #000000; font-weight: bold">in</span> main
x <span style="color: #333333">=</span> t<span style="color: #333333">.</span>timeit(number)
File <span style="background-color: #fff0f0">&quot;/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/timeit.py&quot;</span>, line <span style="color: #0000DD; font-weight: bold">178</span>, <span style="color: #000000; font-weight: bold">in</span> timeit
timing <span style="color: #333333">=</span> <span style="color: #007020">self</span><span style="color: #333333">.</span>inner(it, <span style="color: #007020">self</span><span style="color: #333333">.</span>timer)
File <span style="background-color: #fff0f0">&quot;&lt;timeit-src&gt;&quot;</span>, line <span style="color: #0000DD; font-weight: bold">6</span>, <span style="color: #000000; font-weight: bold">in</span> inner
<span style="color: #008800; font-weight: bold">for</span> i <span style="color: #000000; font-weight: bold">in</span> xrange(<span style="color: #0000DD; font-weight: bold">1000000</span>):
<span style="color: #FF0000; font-weight: bold">NameError</span>: name <span style="background-color: #fff0f0">&#39;xrange&#39;</span> <span style="color: #000000; font-weight: bold">is</span> <span style="color: #000000; font-weight: bold">not</span> defined
</pre></div>
<a id='raising_exceptions'></a>
<br>
<br>
### Raising exceptions
[[back to Python 2.x vs 3.x overview](#py23_overview)]
Where Python 2 accepts both notations, the 'old' and the 'new' way, Python 3 chokes (and raises a `SyntaxError` in turn) if we don't enclose the exception argument in parentheses:
<br>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #008800; font-weight: bold">raise</span> <span style="color: #FF0000; font-weight: bold">IOError</span>, <span style="background-color: #fff0f0">&quot;file error&quot;</span>
Traceback (most recent call last):
File <span style="background-color: #fff0f0">&quot;&lt;stdin&gt;&quot;</span>, line <span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333">&lt;</span>module<span style="color: #333333">&gt;</span>
<span style="color: #FF0000; font-weight: bold">IOError</span>: file error
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #008800; font-weight: bold">raise</span> <span style="color: #FF0000; font-weight: bold">IOError</span>(<span style="background-color: #fff0f0">&quot;file error&quot;</span>)
Traceback (most recent call last):
File <span style="background-color: #fff0f0">&quot;&lt;stdin&gt;&quot;</span>, line <span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333">&lt;</span>module<span style="color: #333333">&gt;</span>
<span style="color: #FF0000; font-weight: bold">IOError</span>: file error
<span style="color: #888888"># Python 3 </span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #008800; font-weight: bold">raise</span> <span style="color: #FF0000; font-weight: bold">IOError</span>, <span style="background-color: #fff0f0">&quot;file error&quot;</span>
File <span style="background-color: #fff0f0">&quot;&lt;stdin&gt;&quot;</span>, line <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #008800; font-weight: bold">raise</span> <span style="color: #FF0000; font-weight: bold">IOError</span>, <span style="background-color: #fff0f0">&quot;file error&quot;</span>
<span style="color: #333333">^</span>
<span style="color: #FF0000; font-weight: bold">SyntaxError</span>: invalid syntax
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #008800; font-weight: bold">raise</span> <span style="color: #FF0000; font-weight: bold">IOError</span>(<span style="background-color: #fff0f0">&quot;file error&quot;</span>)
Traceback (most recent call last):
File <span style="background-color: #fff0f0">&quot;&lt;stdin&gt;&quot;</span>, line <span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333">&lt;</span>module<span style="color: #333333">&gt;</span>
<span style="color: #FF0000; font-weight: bold">OSError</span>: file error
</pre></div>
<a id='handling_exceptions'></a>
<br>
<br>
### Handling exceptions
[[back to Python 2.x vs 3.x overview](#py23_overview)]
Also the handling of exceptions has slightly changed in Python 3. Now, we have to use the `as` keyword!
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #008800; font-weight: bold">try</span>:
<span style="color: #333333">...</span> blabla
<span style="color: #333333">...</span> <span style="color: #008800; font-weight: bold">except</span> <span style="color: #FF0000; font-weight: bold">NameError</span>, err:
<span style="color: #333333">...</span> <span style="color: #007020">print</span> err, <span style="background-color: #fff0f0">&#39;--&gt; our error msg&#39;</span>
<span style="color: #333333">...</span>
name <span style="background-color: #fff0f0">&#39;blabla&#39;</span> <span style="color: #000000; font-weight: bold">is</span> <span style="color: #000000; font-weight: bold">not</span> defined <span style="color: #333333">--&gt;</span> our error msg
<span style="color: #888888"># Python 3</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #008800; font-weight: bold">try</span>:
<span style="color: #333333">...</span> blabla
<span style="color: #333333">...</span> <span style="color: #008800; font-weight: bold">except</span> <span style="color: #FF0000; font-weight: bold">NameError</span> <span style="color: #008800; font-weight: bold">as</span> err:
<span style="color: #333333">...</span> <span style="color: #007020">print</span>(err, <span style="background-color: #fff0f0">&#39;--&gt; our error msg&#39;</span>)
<span style="color: #333333">...</span>
name <span style="background-color: #fff0f0">&#39;blabla&#39;</span> <span style="color: #000000; font-weight: bold">is</span> <span style="color: #000000; font-weight: bold">not</span> defined <span style="color: #333333">--&gt;</span> our error msg
</pre></div>
<a id='next_next'></a>
<br>
<br>
### The `next()` function and `.next()` method
[[back to Python 2.x vs 3.x overview](#py23_overview)]
Where you can use both function and method in Python 2.7.5, the `next()` function is all that remain in Python 3!
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Python 2</span>
<span style="color: #333333">&gt;&gt;&gt;</span> my_generator <span style="color: #333333">=</span> (letter <span style="color: #008800; font-weight: bold">for</span> letter <span style="color: #000000; font-weight: bold">in</span> <span style="background-color: #fff0f0">&#39;abcdefg&#39;</span>)
<span style="color: #333333">&gt;&gt;&gt;</span> my_generator<span style="color: #333333">.</span>next()
<span style="background-color: #fff0f0">&#39;a&#39;</span>
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">next</span>(my_generator)
<span style="background-color: #fff0f0">&#39;b&#39;</span>
<span style="color: #888888"># Python 3</span>
<span style="color: #333333">&gt;&gt;&gt;</span> my_generator <span style="color: #333333">=</span> (letter <span style="color: #008800; font-weight: bold">for</span> letter <span style="color: #000000; font-weight: bold">in</span> <span style="background-color: #fff0f0">&#39;abcdefg&#39;</span>)
<span style="color: #333333">&gt;&gt;&gt;</span> <span style="color: #007020">next</span>(my_generator)
<span style="background-color: #fff0f0">&#39;a&#39;</span>
<span style="color: #333333">&gt;&gt;&gt;</span> my_generator<span style="color: #333333">.</span>next()
Traceback (most recent call last):
File <span style="background-color: #fff0f0">&quot;&lt;stdin&gt;&quot;</span>, line <span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333">&lt;</span>module<span style="color: #333333">&gt;</span>
<span style="color: #FF0000; font-weight: bold">AttributeError</span>: <span style="background-color: #fff0f0">&#39;generator&#39;</span> <span style="color: #007020">object</span> has no attribute <span style="background-color: #fff0f0">&#39;next&#39;</span>
</pre></div>
<a id='loop_leak'></a>
<br>
<br>
### In Python 3.x for-loop variables don't leak into the global namespace anymore
[[back to Python 2.x vs 3.x overview](#py23_overview)]
This goes back to a change that was made in Python 3.x and is described in [Whats New In Python 3.0](https://docs.python.org/3/whatsnew/3.0.html) as follows:
"List comprehensions no longer support the syntactic form `[... for var in item1, item2, ...]`. Use `[... for var in (item1, item2, ...)]` instead. Also note that list comprehensions have different semantics: they are closer to syntactic sugar for a generator expression inside a `list()` constructor, and in particular the loop control variables are no longer leaked into the surrounding scope."
<br>
`[In:]`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">from</span> <span style="color: #0e84b5; font-weight: bold">platform</span> <span style="color: #008800; font-weight: bold">import</span> python_version
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;This code cell was executed in Python&#39;</span>, python_version())
i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #007020">print</span>([i <span style="color: #008800; font-weight: bold">for</span> i <span style="color: #000000; font-weight: bold">in</span> <span style="color: #007020">range</span>(<span style="color: #0000DD; font-weight: bold">5</span>)])
<span style="color: #007020">print</span>(i, <span style="background-color: #fff0f0">&#39;-&gt; i in global&#39;</span>)
</pre></div>
<br>
`[Out:]`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">This code cell was executed in Python 3.3.5
[0, 1, 2, 3, 4]
1 -&gt; i in global
</pre></div>
<br>
<br>
<br>
`[In:]`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">from</span> <span style="color: #0e84b5; font-weight: bold">platform</span> <span style="color: #008800; font-weight: bold">import</span> python_version
<span style="color: #007020">print</span> <span style="background-color: #fff0f0">&#39;This code cell was executed in Python&#39;</span>, python_version()
i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #007020">print</span> [i <span style="color: #008800; font-weight: bold">for</span> i <span style="color: #000000; font-weight: bold">in</span> <span style="color: #007020">range</span>(<span style="color: #0000DD; font-weight: bold">5</span>)]
<span style="color: #007020">print</span> i, <span style="background-color: #fff0f0">&#39;-&gt; i in global&#39;</span>
</pre></div>
<br>
`[Out:]`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">This code cell was executed in Python 2.7.6
[0, 1, 2, 3, 4]
4 -&gt; i in global
</pre></div>
<a id='compare_unorder'></a>
<br>
<br>
#### Python 3.x prevents us from comparing unorderable types
[[back to Python 2.x vs 3.x overview](#py23_overview)]
<br>
`[In:]`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">from</span> <span style="color: #0e84b5; font-weight: bold">platform</span> <span style="color: #008800; font-weight: bold">import</span> python_version
<span style="color: #007020">print</span> <span style="background-color: #fff0f0">&#39;This code cell was executed in Python&#39;</span>, python_version()
<span style="color: #007020">print</span> [<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">&gt;</span> <span style="background-color: #fff0f0">&#39;foo&#39;</span>
<span style="color: #007020">print</span> (<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>) <span style="color: #333333">&gt;</span> <span style="background-color: #fff0f0">&#39;foo&#39;</span>
<span style="color: #007020">print</span> [<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">&gt;</span> (<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>)
</pre></div>
<br>
`[Out:]`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">This code cell was executed in Python 2.7.6
False
True
False
</pre></div>
<br>
<br>
<br>
`[In:]`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">from</span> <span style="color: #0e84b5; font-weight: bold">platform</span> <span style="color: #008800; font-weight: bold">import</span> python_version
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;This code cell was executed in Python&#39;</span>, python_version())
<span style="color: #007020">print</span>([<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">&gt;</span> <span style="background-color: #fff0f0">&#39;foo&#39;</span>)
<span style="color: #007020">print</span>((<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>) <span style="color: #333333">&gt;</span> <span style="background-color: #fff0f0">&#39;foo&#39;</span>)
<span style="color: #007020">print</span>([<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">&gt;</span> (<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>))
</pre></div>
`[Out:]`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">This code cell was executed <span style="color: #000000; font-weight: bold">in</span> Python <span style="color: #6600EE; font-weight: bold">3.3</span><span style="color: #333333">.</span><span style="color: #0000DD; font-weight: bold">5</span>
<span style="color: #333333">---------------------------------------------------------------------------</span>
<span style="color: #FF0000; font-weight: bold">TypeError</span> Traceback (most recent call last)
<span style="color: #333333">&lt;</span>ipython<span style="color: #333333">-</span><span style="color: #007020">input</span><span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">3</span><span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">1</span>d774c677f73<span style="color: #333333">&gt;</span> <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333">&lt;</span>module<span style="color: #333333">&gt;</span>()
<span style="color: #0000DD; font-weight: bold">2</span> <span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;This code cell was executed in Python&#39;</span>, python_version())
<span style="color: #0000DD; font-weight: bold">3</span>
<span style="color: #333333">----&gt;</span> <span style="color: #0000DD; font-weight: bold">4</span> [<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">&gt;</span> <span style="background-color: #fff0f0">&#39;foo&#39;</span>
<span style="color: #0000DD; font-weight: bold">5</span> (<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>) <span style="color: #333333">&gt;</span> <span style="background-color: #fff0f0">&#39;foo&#39;</span>
<span style="color: #0000DD; font-weight: bold">6</span> [<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">&gt;</span> (<span style="color: #0000DD; font-weight: bold">1</span>, <span style="color: #0000DD; font-weight: bold">2</span>)
<span style="color: #FF0000; font-weight: bold">TypeError</span>: unorderable types: <span style="color: #007020">list</span>() <span style="color: #333333">&gt;</span> <span style="color: #007020">str</span>()
</pre></div>

View File

@ -1,579 +0,0 @@
# A Beginner's Guide to Python's Namespaces, Scope Resolution, and the LEGB Rule #
This is a short tutorial about Python's namespaces and the scope resolution for variable names using the LEGB-rule. The following sections will provide short example code blocks that should illustrate the problem followed by short explanations. You can simply read this tutorial from start to end, but I'd like to encourage you to execute the code snippets - you can either copy & paste them, or for your convenience, simply [download it as IPython notebook](https://raw.githubusercontent.com/rasbt/python_reference/master/tutorials/scope_resolution_legb_rule.ipynb).
<br>
<br>
## Objectives
- Namespaces and scopes - where does Python look for variable names?
- Can we define/reuse variable names for multiple objects at the same time?
- In which order does Python search different namespaces for variable names?
<br>
<br>
## Sections
- [Introduction to namespaces and scopes](#introduction)
- [1. LG - Local and Global scopes](#section_1)
- [2. LEG - Local, Enclosed, and Global scope](#section_2)
- [3. LEGB - Local, Enclosed, Global, Built-in](#section_3)
- [Self-assessment exercise](#assessment)
- [Conclusion](#conclusion)
- [Solutions](#solutions)
- [Warning: For-loop variables "leaking" into the global namespace](#for_loop)
<a name="introduction"></a>
<br>
<br>
##Introduction to Namespaces and Scopes
<br>
###Namespaces
<br>
Roughly speaking, namespaces are just containers for mapping names to objects. As you might have already heard, everything in Python - literals, lists, dictionaries, functions, classes, etc. - is an object.
Such a "name-to-object" mapping allows us to access an object by a name that we've assigned to it. E.g., if we make a simple string assignment via `a_string = "Hello string"`, we created a reference to the `"Hello string"` object, and henceforth we can access via its variable name `a_string`.
We can picture a namespace as a Python dictionary structure, where the dictionary keys represent the names and the dictionary values the object itself (and this is also how namespaces are currently implemented in Python), e.g.,
<pre>a_namespace = {'name_a':object_1, 'name_b':object_2, ...}</pre>
Now, the tricky part is that we have multiple independent namespaces in Python, and names can be reused for different namespaces (only the objects are unique, for example:
<pre>a_namespace = {'name_a':object_1, 'name_b':object_2, ...}
b_namespace = {'name_a':object_3, 'name_b':object_4, ...}</pre>
For example, every time we call a `for-loop` or define a function, it will create its own namespace. Namespaces also have different levels of hierarchy (the so-called "scope"), which we will discuss in more detail in the next section.
<br>
<br>
### Scope
In the section above, we have learned that namespaces can exist independently from each other and that they are structured in a certain hierarchy, which brings us to the concept of "scope". The "scope" in Python defines the "hierarchy level" in which we search namespaces for certain "name-to-object" mappings.
For example, let us consider the following code:
`Input:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">foo</span>():
i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">5</span>
<span style="color: #007020">print</span>(i, <span style="background-color: #fff0f0">&#39;in foo()&#39;</span>)
<span style="color: #007020">print</span>(i, <span style="background-color: #fff0f0">&#39;global&#39;</span>)
foo()
</pre></div>
`Output:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">1 global</span>
<span style="color: #888888">5 in foo()</span>
</pre></div>
<br>
<br>
Here, we just defined the variable name `i` twice, once on the `foo` function.
- `foo_namespace = {'i':object_3, ...}`
- `global_namespace = {'i':object_1, 'name_b':object_2, ...}`
So, how does Python now which namespace it has to search if we want to print the value of the variable `i`? This is where Python's LEGB-rule comes into play, which we will discuss in the next section.
<br>
### Tip:
If we want to print out the dictionary mapping of the global and local variables, we can use the
the functions `global()` and `local()
`Input:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">#print(globals()) # prints global namespace</span>
<span style="color: #888888">#print(locals()) # prints local namespace</span>
glob <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">foo</span>():
loc <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">5</span>
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;loc in foo():&#39;</span>, <span style="background-color: #fff0f0">&#39;loc&#39;</span> <span style="color: #000000; font-weight: bold">in</span> <span style="color: #007020">locals</span>())
foo()
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;loc in global:&#39;</span>, <span style="background-color: #fff0f0">&#39;loc&#39;</span> <span style="color: #000000; font-weight: bold">in</span> <span style="color: #007020">globals</span>())
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;glob in global:&#39;</span>, <span style="background-color: #fff0f0">&#39;foo&#39;</span> <span style="color: #000000; font-weight: bold">in</span> <span style="color: #007020">globals</span>())
</pre></div>
`Output:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">loc in foo(): True</span>
<span style="color: #888888">loc in global: False</span>
<span style="color: #888888">glob in global: True</span>
</pre></div>
<br>
<br>
### Scope resolution for variable names via the LEGB rule.
We have seen that multiple namespaces can exist independently from each other and that they can contain the same variable names on different hierachy levels. The "scope" defines on which hierarchy level Python searches for a particular "variable name" for its associated object. Now, the next question is: "In which order does Python search the different levels of namespaces before it finds the name-to-object' mapping?"
To answer is: It uses the LEGB-rule, which stands for
**Local -> Enclosed -> Global -> Built-in**,
where the arrows should denote the direction of the namespace-hierarchy search order.
- *Local* can be inside a function or class method, for example.
- *Enclosed* can be its `enclosing` function, e.g., if a function is wrapped inside another function.
- *Global* refers to the uppermost level of the executing script itself, and
- *Built-in* are special names that Python reserves for itself.
So, if a particular name:object mapping cannot be found in the local namespaces, the namespaces of the enclosed scope are being searched next. If the search in the enclosed scope is unsuccessful, too, Python moves on to the global namespace, and eventually, it will search the global namespaces (side note: if a name cannot found in any of the namespaces, a *NameError* will is raised).
**Note**:
Namespaces can also be further nested, for example if we import modules, or if we are defining new classes. In those cases we have to use prefixes to access those nested namespaces. Let me illustrate this concept in the following code block:
`Input:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">numpy</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">math</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">scipy</span>
<span style="color: #007020">print</span>(math<span style="color: #333333">.</span>pi, <span style="background-color: #fff0f0">&#39;from the math module&#39;</span>)
<span style="color: #007020">print</span>(numpy<span style="color: #333333">.</span>pi, <span style="background-color: #fff0f0">&#39;from the numpy package&#39;</span>)
<span style="color: #007020">print</span>(scipy<span style="color: #333333">.</span>pi, <span style="background-color: #fff0f0">&#39;from the scipy package&#39;</span>)
</pre></div>
`Output:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">3.141592653589793 from the math module</span>
<span style="color: #888888">3.141592653589793 from the numpy package</span>
<span style="color: #888888">3.141592653589793 from the scipy package</span>
</pre></div>
<br>
<br>
(This is also why we have to be careful if we import modules via "`from a_module import *`", since it loads the variable names into the global namespace and could potentially overwrite already existing variable names)
<br>
<a name='section1'></a>
<br>
<br>
![LEGB figure](../Images/scope_resolution_1.png)
<br>
<br>
<a name="section_1"></a>
<br>
<br>
## 1. LG - Local and Global scopes
<a name='example1.1'></a>
**Example 1.1**
As a warm-up exercise, let us first forget about the enclosed (E) and built-in (B) scopes in the LEGB rule and only take a look at LG - the local and global scopes.
What does the following code print?
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">a_var <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;global variable&#39;</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">a_func</span>():
<span style="color: #007020">print</span>(a_var, <span style="background-color: #fff0f0">&#39;[ a_var inside a_func() ]&#39;</span>)
a_func()
<span style="color: #007020">print</span>(a_var, <span style="background-color: #fff0f0">&#39;[ a_var outside a_func() ]&#39;</span>)
</pre></div>
**a)**
<pre>raises an error</pre>
**b)**
<pre>
global value [ a_var outside a_func() ]</pre>
**c)**
<pre>global value [ a_var in a_func() ]
global value [ a_var outside a_func() ]</pre>
[[go to solution](#solutions)]
### Here is why:
We call `a_func()` first, which is supposed to print the value of `a_var`. According to the LEGB rule, the function will first look in its own local scope (L) if `a_var` is defined there. Since `a_func()` does not define its own `a_var`, it will look one-level above in the global scope (G) in which `a_var` has been defined previously.
<br>
<br>
<a name='example1.2'></a>
**Example 1.2**
Now, let us define the variable `a_var` in the global and the local scope.
Can you guess what the following code will produce?
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">a_var <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;global value&#39;</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">a_func</span>():
a_var <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;local value&#39;</span>
<span style="color: #007020">print</span>(a_var, <span style="background-color: #fff0f0">&#39;[ a_var inside a_func() ]&#39;</span>)
a_func()
<span style="color: #007020">print</span>(a_var, <span style="background-color: #fff0f0">&#39;[ a_var outside a_func() ]&#39;</span>)
</pre></div>
**a)**
<pre>raises an error</pre>
**b)**
<pre>local value [ a_var in a_func() ]
global value [ a_var outside a_func() ]</pre>
**c)**
<pre>global value [ a_var in a_func() ]
global value [ a_var outside a_func() ]</pre>
[[go to solution](#solutions)]
### Here is why:
When we call `a_func()`, it will first look in its local scope (L) for `a_var`, since `a_var` is defined in the local scope of `a_func`, its assigned value `local variable` is printed. Note that this doesn't affect the global variable, which is in a different scope.
<br>
However, it is also possible to modify the global by, e.g., re-assigning a new value to it if we use the global keyword as the following example will illustrate:
`Input:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">a_var <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;global value&#39;</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">a_func</span>():
<span style="color: #008800; font-weight: bold">global</span> a_var
a_var <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;local value&#39;</span>
<span style="color: #007020">print</span>(a_var, <span style="background-color: #fff0f0">&#39;[ a_var inside a_func() ]&#39;</span>)
<span style="color: #007020">print</span>(a_var, <span style="background-color: #fff0f0">&#39;[ a_var outside a_func() ]&#39;</span>)
a_func()
<span style="color: #007020">print</span>(a_var, <span style="background-color: #fff0f0">&#39;[ a_var outside a_func() ]&#39;</span>)
</pre></div>
`Output:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">**a)**</span>
<span style="color: #888888">&lt;pre&gt;raises an error&lt;/pre&gt;</span>
<span style="color: #888888">**b)** </span>
<span style="color: #888888">&lt;pre&gt;</span>
<span style="color: #888888">global value [ a_var outside a_func() ]&lt;/pre&gt;</span>
<span style="color: #888888">**c)** </span>
<span style="color: #888888">&lt;pre&gt;global value [ a_var in a_func() ] </span>
<span style="color: #888888">global value [ a_var outside a_func() ]&lt;/pre&gt;</span>
</pre></div>
But we have to be careful about the order: it is easy to raise an `UnboundLocalError` if we don't explicitly tell Python that we want to use the global scope and try to modify a variable's value (remember, the right side of an assignment operation is executed first):
`Input:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">a_var <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">a_func</span>():
a_var <span style="color: #333333">=</span> a_var <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #007020">print</span>(a_var, <span style="background-color: #fff0f0">&#39;[ a_var inside a_func() ]&#39;</span>)
<span style="color: #007020">print</span>(a_var, <span style="background-color: #fff0f0">&#39;[ a_var outside a_func() ]&#39;</span>)
a_func()
</pre></div>
`Output:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #333333">---------------------------------------------------------------------------</span>
<span style="color: #FF0000; font-weight: bold">UnboundLocalError</span> Traceback (most recent call last)
<span style="color: #333333">&lt;</span>ipython<span style="color: #333333">-</span><span style="color: #007020">input</span><span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">4</span><span style="color: #333333">-</span>a6cdd0ee9a55<span style="color: #333333">&gt;</span> <span style="color: #000000; font-weight: bold">in</span> <span style="color: #333333">&lt;</span>module<span style="color: #333333">&gt;</span>()
<span style="color: #0000DD; font-weight: bold">6</span>
<span style="color: #0000DD; font-weight: bold">7</span> <span style="color: #007020">print</span>(a_var, <span style="background-color: #fff0f0">&#39;[ a_var outside a_func() ]&#39;</span>)
<span style="color: #333333">----&gt;</span> <span style="color: #0000DD; font-weight: bold">8</span> a_func()
<span style="color: #333333">&lt;</span>ipython<span style="color: #333333">-</span><span style="color: #007020">input</span><span style="color: #333333">-</span><span style="color: #0000DD; font-weight: bold">4</span><span style="color: #333333">-</span>a6cdd0ee9a55<span style="color: #333333">&gt;</span> <span style="color: #000000; font-weight: bold">in</span> a_func()
<span style="color: #0000DD; font-weight: bold">2</span>
<span style="color: #0000DD; font-weight: bold">3</span> <span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">a_func</span>():
<span style="color: #333333">----&gt;</span> <span style="color: #0000DD; font-weight: bold">4</span> a_var <span style="color: #333333">=</span> a_var <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #0000DD; font-weight: bold">5</span> <span style="color: #007020">print</span>(a_var, <span style="background-color: #fff0f0">&#39;[ a_var inside a_func() ]&#39;</span>)
<span style="color: #0000DD; font-weight: bold">6</span>
<span style="color: #FF0000; font-weight: bold">UnboundLocalError</span>: local variable <span style="background-color: #fff0f0">&#39;a_var&#39;</span> referenced before assignment
<span style="color: #0000DD; font-weight: bold">1</span> [ a_var outside a_func() ]
</pre></div>
<br>
<br>
<a name="section_2"></a>
<br>
<br>
## 2. LEG - Local, Enclosed, and Global scope
Now, let us introduce the concept of the enclosed (E) scope. Following the order "Local -> Enclosed -> Global", can you guess what the following code will print?
<a name='example2'></a>
**Example 2.1**
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">a_var <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;global value&#39;</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">outer</span>():
a_var <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;enclosed value&#39;</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">inner</span>():
a_var <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;local value&#39;</span>
<span style="color: #007020">print</span>(a_var)
inner()
outer()
</pre></div>
**a)**
<pre>global value</pre>
**b)**
<pre>enclosed value</pre>
**c)**
<pre>local value</pre>
[[go to solution](#solutions)]
### Here is why:
Let us quickly recapitulate what we just did: We called `outer()`, which defined the variable `a_var` locally (next to an existing `a_var` in the global scope). Next, the `outer()` function called `inner()`, which in turn defined a variable with of name `a_var` as well. The `print()` function inside `inner()` searched in the local scope first (L->E) before it went up in the scope hierarchy, and therefore it printed the value that was assigned in the local scope.
Similar to the concept of the `global` keyword, which we have seen in the section above, we can use the keyword `nonlocal` inside the inner function to explicitly access a variable from the outer (enclosed) scope in order to modify its value.
Note that the `nonlocal` keyword was added in Python 3.x and is not implemented in Python 2.x (yet).
`Input:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">a_var <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;global value&#39;</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">outer</span>():
a_var <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;local value&#39;</span>
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;outer before:&#39;</span>, a_var)
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">inner</span>():
<span style="color: #008800; font-weight: bold">nonlocal</span> a_var
a_var <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;inner value&#39;</span>
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;in inner():&#39;</span>, a_var)
inner()
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&quot;outer after:&quot;</span>, a_var)
outer()
</pre></div>
`Output:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">outer before: local value</span>
<span style="color: #888888">in inner(): inner value</span>
<span style="color: #888888">outer after: inner value</span>
</pre></div>
<a name="section_3"></a>
<br>
<br>
<br>
## 3. LEGB - Local, Enclosed, Global, Built-in
To wrap up the LEGB rule, let us come to the built-in scope. Here, we will define our "own" length-function, which happens to bear the same name as the in-built `len()` function. What outcome do you expect if we'd execute the following code?
<a name='example3'></a>
**Example 3**
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">a_var <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;global variable&#39;</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">len</span>(in_var):
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;called my len() function&#39;</span>)
l <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>
<span style="color: #008800; font-weight: bold">for</span> i <span style="color: #000000; font-weight: bold">in</span> in_var:
l <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #008800; font-weight: bold">return</span> l
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">a_func</span>(in_var):
len_in_var <span style="color: #333333">=</span> <span style="color: #007020">len</span>(in_var)
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;Input variable is of length&#39;</span>, len_in_var)
a_func(<span style="background-color: #fff0f0">&#39;Hello, World!&#39;</span>)
</pre></div>
**a)**
<pre>raises an error (conflict with in-built `len()` function)</pre>
**b)**
<pre>called my len() function
Input variable is of length 13</pre>
**c)**
<pre>Input variable is of length 13</pre>
[[go to solution](#solutions)]
### Here is why:
Since the exact same names can be used to map names to different objects - as long as the names are in different name spaces - there is no problem of reusing the name `len` to define our own length function (this is just for demonstration purposes, it is NOT recommended). As we go up in Python's L -> E -> G -> B hierarchy, the function `a_func()` finds `len()` already in the global scope first before it attempts
<a name ="assessment"></a>
<br>
<br>
# Self-assessment exercise
Now, after we went through a couple of exercises, let us quickly check where we are. So, one more time: What would the following code print out?
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">a <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;global&#39;</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">outer</span>():
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">len</span>(in_var):
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;called my len() function: &#39;</span>, end<span style="color: #333333">=</span><span style="background-color: #fff0f0">&quot;&quot;</span>)
l <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>
<span style="color: #008800; font-weight: bold">for</span> i <span style="color: #000000; font-weight: bold">in</span> in_var:
l <span style="color: #333333">+=</span> <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #008800; font-weight: bold">return</span> l
a <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&#39;local&#39;</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">inner</span>():
<span style="color: #008800; font-weight: bold">global</span> <span style="color: #007020">len</span>
<span style="color: #008800; font-weight: bold">nonlocal</span> a
a <span style="color: #333333">+=</span> <span style="background-color: #fff0f0">&#39; variable&#39;</span>
inner()
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;a is&#39;</span>, a)
<span style="color: #007020">print</span>(<span style="color: #007020">len</span>(a))
outer()
<span style="color: #007020">print</span>(<span style="color: #007020">len</span>(a))
<span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;a is&#39;</span>, a)
</pre></div>
<a name="conclusion"
<br>
<br>
[[go to solution](#solutions)]
# Conclusion
I hope this short tutorial was helpful to understand the basic concept of Python's scope resolution order using the LEGB rule. I want to encourage you (as a little self-assessment exercise) to look at the code snippets again tomorrow and check if you can correctly predict all their outcomes.
#### A rule of thumb
In practice, **it is usually a bad idea to modify global variables inside the function scope**, since it often be the cause of confusion and weird errors that are hard to debug.
If you want to modify a global variable via a function, it is recommended to pass it as an argument and reassign the return-value.
For example:
`Input:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">a_var <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">2</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">a_func</span>(some_var):
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #0000DD; font-weight: bold">2</span><span style="color: #333333">**</span><span style="color: #0000DD; font-weight: bold">3</span>
a_var <span style="color: #333333">=</span> a_func(a_var)
<span style="color: #007020">print</span>(a_var)
</pre></div>
`Output:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">8</span>
</pre></div>
<a name = "solutions"></a>
<br>
<br>
## Solutions
In order to prevent you from unintentional spoilers, I have written the solutions in binary format. In order to display the character representation, you just need to execute the following lines of code:
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;Example 1.1:&#39;</span>, <span style="color: #007020">chr</span>(<span style="color: #007020">int</span>(<span style="background-color: #fff0f0">&#39;01100011&#39;</span>,<span style="color: #0000DD; font-weight: bold">2</span>)))
</pre></div>
[[back to example 1.1](#example1.1)]
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;Example 1.2:&#39;</span>, <span style="color: #007020">chr</span>(<span style="color: #007020">int</span>(<span style="background-color: #fff0f0">&#39;01100001&#39;</span>,<span style="color: #0000DD; font-weight: bold">2</span>)))
</pre></div>
[[back to example 1.2](#example1.2)]
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;Example 2:&#39;</span>, <span style="color: #007020">chr</span>(<span style="color: #007020">int</span>(<span style="background-color: #fff0f0">&#39;01100011&#39;</span>,<span style="color: #0000DD; font-weight: bold">2</span>)))
</pre></div>
[[back to example 2](#example2)]
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #007020">print</span>(<span style="background-color: #fff0f0">&#39;Example 3:&#39;</span>, <span style="color: #007020">chr</span>(<span style="color: #007020">int</span>(<span style="background-color: #fff0f0">&#39;01100010&#39;</span>,<span style="color: #0000DD; font-weight: bold">2</span>)))
</pre></div>
[[back to example 3](#example3)]
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Solution to the self-assessment exercise</span>
sol <span style="color: #333333">=</span> <span style="background-color: #fff0f0">&quot;000010100110111101110101011101000110010101110010001010&quot;</span>\
<span style="background-color: #fff0f0">&quot;0000101001001110100000101000001010011000010010000001101001011100110&quot;</span>\
<span style="background-color: #fff0f0">&quot;0100000011011000110111101100011011000010110110000100000011101100110&quot;</span>\
<span style="background-color: #fff0f0">&quot;0001011100100110100101100001011000100110110001100101000010100110001&quot;</span>\
<span style="background-color: #fff0f0">&quot;1011000010110110001101100011001010110010000100000011011010111100100&quot;</span>\
<span style="background-color: #fff0f0">&quot;1000000110110001100101011011100010100000101001001000000110011001110&quot;</span>\
<span style="background-color: #fff0f0">&quot;1010110111001100011011101000110100101101111011011100011101000100000&quot;</span>\
<span style="background-color: #fff0f0">&quot;0011000100110100000010100000101001100111011011000110111101100010011&quot;</span>\
<span style="background-color: #fff0f0">&quot;0000101101100001110100000101000001010001101100000101001100001001000&quot;</span>\
<span style="background-color: #fff0f0">&quot;0001101001011100110010000001100111011011000110111101100010011000010&quot;</span>\
<span style="background-color: #fff0f0">&quot;1101100&quot;</span>
sol_str <span style="color: #333333">=</span><span style="background-color: #fff0f0">&#39;&#39;</span><span style="color: #333333">.</span>join(<span style="color: #007020">chr</span>(<span style="color: #007020">int</span>(sol[i:i<span style="color: #333333">+</span><span style="color: #0000DD; font-weight: bold">8</span>], <span style="color: #0000DD; font-weight: bold">2</span>)) <span style="color: #008800; font-weight: bold">for</span> i <span style="color: #000000; font-weight: bold">in</span> <span style="color: #007020">range</span>(<span style="color: #0000DD; font-weight: bold">0</span>, <span style="color: #007020">len</span>(sol), <span style="color: #0000DD; font-weight: bold">8</span>))
<span style="color: #008800; font-weight: bold">for</span> line <span style="color: #000000; font-weight: bold">in</span> sol_str<span style="color: #333333">.</span>split(<span style="background-color: #fff0f0">&#39;</span><span style="color: #666666; font-weight: bold; background-color: #fff0f0">\n</span><span style="background-color: #fff0f0">&#39;</span>):
<span style="color: #007020">print</span>(line)
</pre></div>
[[back to self-assessment exercise](#assessment)]
<br>
<br>
<a name="for_loop"></a>
## Warning: For-loop variables "leaking" into the global namespace
In contrast to some other programming languages, `for-loops` will use the scope they exist in and leave their defined loop-variable behind.
`Input:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">for</span> a <span style="color: #000000; font-weight: bold">in</span> <span style="color: #007020">range</span>(<span style="color: #0000DD; font-weight: bold">5</span>):
<span style="color: #008800; font-weight: bold">if</span> a <span style="color: #333333">==</span> <span style="color: #0000DD; font-weight: bold">4</span>:
<span style="color: #007020">print</span>(a, <span style="background-color: #fff0f0">&#39;-&gt; a in for-loop&#39;</span>)
<span style="color: #007020">print</span>(a, <span style="background-color: #fff0f0">&#39;-&gt; a in global&#39;</span>)
</pre></div>
`Output:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">4 -&gt; a in for-loop</span>
<span style="color: #888888">4 -&gt; a in global</span>
</pre></div>
**This also applies if we explicitely defined the `for-loop` variable in the global namespace before!** In this case it will rebind the existing variable:
`Input:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">b <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #008800; font-weight: bold">for</span> b <span style="color: #000000; font-weight: bold">in</span> <span style="color: #007020">range</span>(<span style="color: #0000DD; font-weight: bold">5</span>):
<span style="color: #008800; font-weight: bold">if</span> b <span style="color: #333333">==</span> <span style="color: #0000DD; font-weight: bold">4</span>:
<span style="color: #007020">print</span>(b, <span style="background-color: #fff0f0">&#39;-&gt; b in for-loop&#39;</span>)
<span style="color: #007020">print</span>(b, <span style="background-color: #fff0f0">&#39;-&gt; b in global&#39;</span>)
</pre></div>
`Output:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">4 -&gt; b in for-loop</span>
<span style="color: #888888">4 -&gt; b in global</span>
</pre></div>
However, in **Python 3.x**, we can use closures to prevent the for-loop variable to cut into the global namespace. Here is an example (exectuted in Python 3.4):
`Input:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%">i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">1</span>
<span style="color: #007020">print</span>([i <span style="color: #008800; font-weight: bold">for</span> i <span style="color: #000000; font-weight: bold">in</span> <span style="color: #007020">range</span>(<span style="color: #0000DD; font-weight: bold">5</span>)])
<span style="color: #007020">print</span>(i, <span style="background-color: #fff0f0">&#39;-&gt; i in global&#39;</span>)
</pre></div>
`Output:`
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #888888">[0, 1, 2, 3, 4]</span>
<span style="color: #888888">1 -&gt; i in global</span>
</pre></div>
Why did I mention "Python 3.x"? Well, as it happens, the same code executed in Python 2.x would print:
<pre>
4 -> i in global
</pre>
This goes back to a change that was made in Python 3.x and is described in [Whats New In Python 3.0](https://docs.python.org/3/whatsnew/3.0.html) as follows:
"List comprehensions no longer support the syntactic form `[... for var in item1, item2, ...]`. Use `[... for var in (item1, item2, ...)]` instead. Also note that list comprehensions have different semantics: they are closer to syntactic sugar for a generator expression inside a `list()` constructor, and in particular the loop control variables are no longer leaked into the surrounding scope."

View File

@ -1,125 +0,0 @@
[Sebastian Raschka](http://sebastianraschka.com)
last updated: 05/18/2014
- [Link to this IPython Notebook on Github](https://github.com/rasbt/One-Python-benchmark-per-day/blob/master/ipython_nbs/day4_2_cython_numba_parakeet.ipynb)
- [Link to the GitHub Repository One-Python-benchmark-per-day](https://github.com/rasbt/One-Python-benchmark-per-day)
<hr>
I would be happy to hear your comments and suggestions.
Please feel free to drop me a note via
[twitter](https://twitter.com/rasbt), [email](mailto:bluewoodtree@gmail.com), or [google+](https://plus.google.com/118404394130788869227).
<hr>
<a id='top'></a>
# Creating a table of contents with internal links in IPython Notebooks and Markdown documents
**Many people have asked me how I create the table of contents with internal links for my IPython Notebooks and Markdown documents on GitHub.
Well, no (IPython) magic is involved, it is just a little bit of HTML, but I thought it might be worthwhile to write this little how-to tutorial.**
![example table](../Images/ipython_links_ex.png)
<br>
<br>
For example, [click this link](#bottom) to jump to the bottom of the page.
<br>
<br>
<br>
<br>
## The two components to create an internal link
So, how does it work? Basically, all you need are those two components:
1. the destination
2. an internal hyperlink to the destination
![two components](../Images/ipython_links_overview.png)
<br>
###1. The destination
To define the destination (i.e., the section on the page or the cell you want to jump to), you just need to insert an empty HTML anchor tag and give it an **`id`**,
e.g., **`<a id='the_destination'></a>`**
This anchor tag will be invisible if you render it as Markdown in the IPython Notebook.
Note that it would also work if we use the **`name`** attribute instead of **`id`**, but since the **`name`** attribute is not supported by HTML5 anymore, I would suggest to just use the **`id`** attribute, which is also shorter to type.
<br>
###2. The internal hyperlink
Now we have to create the hyperlink to the **`<a id='the_destination'></a>`** anchor tag that we just created.
We can either do this in ye goode olde HTML where we put a fragment identifier in form of a hash mark (`#`) in front of the name,
for example, **`<a href='#the_destination'>Link to the destination'</a>`**
Or alternatively, we can just use the slightly more convenient Markdown syntax:
**`[Link to the destination](#the_destination)`**
**That's all!**
<br>
<br>
## One more piece of advice
Of course it would make sense to place the empty anchor tags for you table of contents just on top of each cell that contains a heading.
E.g.,
`<a id='section2'></a>`
`###Section 2`
`some text ...`
And I did this for a very long time ... until I figured out that it wouldn't render the Markdown properly if you convert the IPython Notebook into HTML (for example, for printing via the print preview option).
But instead of
###Section 2
it would be rendered as
`###Section 2`
which is certainly not what we want (note that it looks normal in the IPython Notebook, but not in the converted HTML version). So my favorite remedy would be to put the `id`-anchor tag into a separate cell just above the section, ideally with some line breaks for nicer visuals.
![img of format problem](../Images/ipython_links_format.png)
<br>
<br>
### Solution 1: id-anchor tag in a separate cell
![img of format problem](../Images/ipython_links_remedy.png)
<br>
<br>
<br>
<br>
<br>
### Solution 2: using header cells
To define the hyperlink anchor tag to this "header cell" is just the text content of the "header cell" connected by dashes. E.g.,
![header cell](../Images/ipython_table_header.png)
`[link to another section](#Another-section)`
<br>
<br>
<br>
<br>
<br>
<br>
[[Click this link and jump to the top of the page](#top)]
You can't see it, but this cell contains a
`<a id='bottom'></a>`
anchor tag just below this text.
<a id='bottom'></a>