Handling Function Creation in Loops: Troubleshooting Late Binding
When attempting to create functions within a loop, a common issue arises. In the example provided, the goal is to generate three functions that return 0, 1, and 2, respectively. However, all three functions end up returning the same value (2). This occurs due to late binding, where the functions defer their evaluation of the variable 'i' until the last possible moment.
Understanding Late Binding
In the code without the fix:
for i in range(3): def f(): return i
Each 'f' looks up 'i' late in the loop's execution, by which time 'i' has reached its final value of 2. Consequently, all three functions return 2, despite the loop intending to create functions returning 0, 1, and 2.
Fixing the Issue
The solution to this problem is to enforce early binding. This can be achieved by passing 'i' as an argument to the 'f' function like this:
for i in range(3): def f(i=i): return i
In this updated code, 'i' is looked up at definition time, when the loop is executed rather than at call time when 'f' is executed.
Alternative Solution Using Closures
Another approach is to use a closure to create a "function factory":
def make_f(i): def f(): return i return f
Within the loop, 'f' can then be created using 'f = make_f(i)'. This approach also ensures early binding, as the function 'make_f' passes the value of 'i' to 'f' at definition time.
The above is the detailed content of Why Do Functions Created in Loops Sometimes Return the Wrong Values?. For more information, please follow other related articles on the PHP Chinese website!