Notes and Thoughts

The keeping of a second brain

Home

Closures in Python capture variables not values

def random_function(s):
    print(s)

letters = []
for s in ["a", "b", "c"]:
    letters.append((s, lambda : random_function(s)))

for url, f in letters:
    f()

This prints

c
c
c

The reason is that the argument is only evaluated when the function is executed.

The way to workaround this is to set it as a default value (“the default-value hack”):

def random_function(s):
    print(s)

letters = []
for s in ["a", "b", "c"]:
    letters.append((s, lambda s=s: random_function(s)))

for url, f in letters:
    f()

The reason this works is that default values are created once when the function is defined. This will print

a
b
c