Closures in Python
While implementing a breadth-first search routine for a graph in Python I wanted to pass in a function to get called every time a vertex is visited. After programming in JavaScript, I immediately used a closure. I hadn’t actually ever used a closure in Python before and thought that nested functions were rather ugly.
It turns out that they work mostly like closures in JavaScript with one major exception; Enclosed variables are read-only. Consequently, assigning to variable in the outer-scope creates a local alias rather than modify the outer variable. To fix this, one must declare the enclosed variable before modifying it with the nonlocal
keyword.
Here is an example:
def outer():
x = 'foo'
print("x is {} in outer before assignment".format(x))
def inner_local():
x = 'bar'
print("x is {} in inner_local after assignment".format(x))
inner_local()
print("x is {} in outer after calling inner_local()".format(x))
def inner_nonlocal():
nonlocal x
x = 'bar'
print("x is {} in inner_nonlocal after assignment".format(x))
inner_nonlocal()
print("x is {} in outer after calling inner_nonlocal()".format(x))
Calling outer()
prints the following:
x is foo in outer before assignment
x is bar in inner_local after assignment
x is foo in outer after calling inner_local()
x is bar in inner_nonlocal after assignment
x is bar in outer after calling inner_nonlocal()