15.04.2013 Views

Core Python Programming (2nd Edition)

Core Python Programming (2nd Edition)

Core Python Programming (2nd Edition)

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

If references are made from inside an inner function to an object defined in any outer scope (but not in<br />

the global scope), the inner function then is known as a closure. The variables defined in the outer<br />

function but used or referred to by the inner function are called free variables. Closures are an important<br />

concept in functional programming languages, with Scheme and Haskell being two of them. Closures are<br />

syntactically simple (as simple as inner functions) yet still very powerful.<br />

A closure combines an inner function's own code and scope along with the scope of an outer function.<br />

Closure lexical variables do not belong to the global namespace scope or the local onethey belong to<br />

someone else's namespace and carry an "on the road" kind of scope. (Note that they differ from objects<br />

in that those variables live in an object's namespace while closure variables live in a function's<br />

namespace and scope.) So why would you want to use closures?<br />

Closures are useful for setting up calculations, hiding state, letting you move around function objects<br />

and scope at will. Closures come in handy in GUI or event-driven programming where a lot of APIs<br />

support callbacks. The same applies for retrieving database rows and processing the data in the exact<br />

same manner. Callbacks are just functions. Closures are functions, too, but they carry some additional<br />

scope with them. They are just functions with an extra feature ... another scope.<br />

You will probably feel that the use of closures draws a strong parallel to partial function application as<br />

introduced earlier in this chapter, but PFA is really more like currying than the use of closures because it<br />

is not as much as about function calling as it is about using variables defined in another scope.<br />

Simple Closure Example<br />

Below is a short example of using closures. We will simulate a counter and also simulate making an<br />

integer mutable by enclosing it as a single element of a list.<br />

def counter(start_at=0):<br />

count = [start_at]<br />

def incr():<br />

count[0] += 1<br />

return count[0]<br />

return incr<br />

The only thing counter() does is to accept an initial value to start counting at and assigns it as the sole<br />

member of the list count. Then an incr() inner function is defined. By using the variable count inside it,<br />

we have created a closure because it now carries with it the scope of counter(). incr() increments the<br />

running count and returns it. Then the final magic is that counter() returns incr, a (callable) function<br />

object.<br />

If we run this interactively, we get the output belownote how similar it looks to instantiating a counter<br />

object and executing the instance:<br />

>>> count = counter(5)<br />

>>> print count()<br />

6<br />

>>> print count()<br />

7

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

Saved successfully!

Ooh no, something went wrong!