'''
There is a pitfall when it comes to closures. This is called late binding, and it
refers to when the value of the free variable is looked up.
'''
'''
This parent function iterates through a range (a generator, covered in another snippet),
and adds a closure function multiple(n) to a list, which is returned. Each time
a new multiple() function is declared, it is appended to the list.
'''
def make_multipliers():
multiples = []
for i in range(3):
def multiple(n):
return i*n
multiples.append(multiple)
return multiples
b = make_multipliers
c = b()
for func in c:
print(func(2))
'''
It would not be irrational to assume that this function would print out the numbers
0, 2, 4. However, i is a free variable. Because of this, when make_multipliers()
is called, i has already gone through its range of 0, 1, 2. This means that,
at the time func(2) is called, i = 2, and all returned values = 4.
'''