Last active
December 14, 2015 05:29
-
-
Save maxcountryman/5035489 to your computer and use it in GitHub Desktop.
Some notes on closures in Python.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
>>> foo = [] | |
>>> for i in range(10): | |
... foo.append(lambda: i) | |
>>> bar = [] | |
>>> for i in range(10): | |
... # `bar.append(lambda j=i: j)` may be easier to see | |
... bar.append(lambda i=i: i) | |
>>> baz = [] | |
>>> for i in range(10): | |
... baz.append((lambda: lambda i)()) | |
>>> qux = [] | |
>>> for i in range(10): | |
... # or: `qux.append((lambda j: lambda j)(i))` | |
... qux.append((lambda i: lambda: i)(i)) | |
# Prints 9 9 ... 9 because the bound value of `i` is evaluated when | |
# the function is called, i.e. after the loop is executed, so `9`. | |
>>> map(lambda x: x(), foo) | |
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9] | |
# However here `i` is bound in the defintion of the function, via | |
# named arguments. A function object is created each iteration and | |
# thus the value is bound each time as a default. Prints 1 2 ... 9 | |
>>> map(lambda x: x(), bar) | |
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | |
# This produces the same result as the first for loop and for the | |
# same reason: `i` is bound to the value after the loop has | |
# terminated due to the closure. | |
>>> map(lambda x: x(), baz) | |
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9] | |
# Finally this approach is similar to the JavaScript idiom. A | |
# function is wrapped in a function. But a variable `i` is passed | |
# into the first function, which in turn creates a closure over | |
# the wrapped function. Because the outer function is called as the | |
# loop is iterating and `i` is passed in, the bound value of the | |
# current iteration is then again bound to a new scope around the | |
#inner the function. | |
>>> map(lambda x: x(), qux) | |
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment