Closures in Python
A closure is data attached to code (pretty simple, eh?). I use them for:
- Replacing hard coded constants
- Eleminating globals
- Providing consistent function signatures
- Implementing Object Orientation
Here is a closure in python:
def makeInc(x):Closures in python are created by function calls. Here, the call to makeInc creates a binding for x that is referenced inside the function inc. Each call to makeInc creates a new instance of this function, but each instance has a link to a different binding of x. The example shows the closure of x being used to eliminate either a global or a constant, depending on the nature of x.
def inc(y):
# x is "closed" in the definition of inc
return y + x
return inc
inc5 = makeInc(5)
inc10 = makeInc(10)
inc5 (5) # returns 10
inc10(5) # returns 15
import timeIn python, all methods (but not functions) are closures ... sort of. The method definition foo.update closes the class foo. The value of g.update is a closure that stores the value of g and passes that as the first argument of foo.self, hence the first argument of a method in python is self. Details aside, it is important to note that the designers of python have gone out of their way so that you can pass g.update by itself to another function and have it continue to work correctly.
keepRunning = True
updates = []
def runLoop():
while (keepRunning):
for u in updates:
u()
class foo:
def __init__(self, x = 0):
self.x = x
def update():
print self.x
self.x += 1
f = foo()
g = foo(2)
updates.extend([f.update, g.update])
Caveats
In some languages, the variable bindings contained in a closure behave just like any other variables. Alas, in python they are read-only. This is similar to Java, and has the same solution: closing container objects. Closure of a dictionary or array won't let you assign a new dictionary or array, but will let you change the contents of the container. This is a common use pattern - every time you set a variable on self, you are changing the contents of a closed dictionary.

