16.01.2014 Views

Beginning Python - From Novice to Professional

Beginning Python - From Novice to Professional

Beginning Python - From Novice to Professional

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

128 CHAPTER 6 ■ ABSTRACTION<br />

■Note Use global variables only when you have <strong>to</strong>. They tend <strong>to</strong> make your code less readable and less<br />

robust. Local variables make your program more abstract because they are “hidden” inside functions.<br />

NESTED SCOPES<br />

<strong>Python</strong>’s scopes may (from <strong>Python</strong> 2.2 on) be nested. This means that you can (among other things) write<br />

functions like the following:<br />

def multiplier(fac<strong>to</strong>r):<br />

def multiplyByFac<strong>to</strong>r(number):<br />

return number*fac<strong>to</strong>r<br />

return multiplyByFac<strong>to</strong>r<br />

One function is inside another, and the outer function returns the inner one. Each time the outer function<br />

is called, the inner one gets redefined, and each time, the variable fac<strong>to</strong>r may have a new value. With nested<br />

scopes, this variable from the outer local scope (of multiplier) is accessible in the inner function later on,<br />

as follows:<br />

>>> double = multiplier(2)<br />

>>> double(5)<br />

10<br />

>>> triple = multiplier(3)<br />

>>> triple(3)<br />

9<br />

>>> multiplier(5)(4)<br />

20<br />

A function such as multiplyByFac<strong>to</strong>r that s<strong>to</strong>res its enclosing scopes is called a closure.<br />

If, for some reason, you’re using <strong>Python</strong> 2.1, you have <strong>to</strong> add the following line at the beginning of<br />

your program:<br />

from __future__ import nested_scopes<br />

In older versions of <strong>Python</strong>, variables from surrounding nested scopes are not available. You get an error<br />

message like this:<br />

>>> double = multiplier(2)<br />

>>> double(2)<br />

Traceback (innermost last):<br />

File "", line 1, in ?<br />

File "", line 3, in multiplyByFac<strong>to</strong>r<br />

NameError: fac<strong>to</strong>r<br />

Because old versions of <strong>Python</strong> only have local and global scopes, and fac<strong>to</strong>r is not a local variable in<br />

multiplyByFac<strong>to</strong>r, <strong>Python</strong> assumes that it must be a global variable. But it isn’t, so you get an exception.<br />

To s<strong>to</strong>re a variable from an enclosing scope, you can use a trick—s<strong>to</strong>ring it as a default value:

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!