0

Right now I think I have understood most of the problems related to default value in Python. The questions on Stackoverflow has been a great help, but there is one case/example that they do not address. That example is in this link: http://effbot.org/zone/default-values.htm Here is the part in question:

Finally, it should be noted that more advanced Python code often uses this mechanism to its advantage; for example, if you create a bunch of UI buttons in a loop, you might try something like:

for i in range(10):
    def callback():
        print "clicked button", i
    UI.Button("button %s" % i, callback)

only to find that all callbacks print the same value (most likely 9, in this case). The reason for this is that Python’s nested scopes bind to variables, not object values, so all callback instances will see the current (=last) value of the “i” variable. To fix this, use explicit binding:

for i in range(10):
    def callback(i=i):
        print "clicked button", i
    UI.Button("button %s" % i, callback)

The i=i part binds the parameter i (a local variable) to the current value of the outer variable i. I can understand why the second example works the way it does: in the def line, the i in the function is explicitly bounded to the i in the for (this is done during the "def" statement, namely definition-time). But what I don't get is how the first example works. It seems to me that the i variable there is bounded during run-time but then shouldn't it also be the same as the second one? Thank you very much.

Adam Smith
  • 52,157
  • 12
  • 73
  • 112
Dang Manh Truong
  • 795
  • 2
  • 10
  • 35
  • @TigerhawkT3 : No, this is not a duplicate Your link only mention an example of default value without a loop, while my question is concerned with behaviour of a function in a loop. These are 2 different examples. – Dang Manh Truong Oct 18 '15 at 05:06
  • Then try http://stackoverflow.com/questions/19837486/python-lambda-in-a-loop. – TigerhawkT3 Oct 18 '15 at 05:11
  • Read [this answer](http://stackoverflow.com/a/19837590/2617068) in particular. – TigerhawkT3 Oct 18 '15 at 05:12
  • I think Tigerhawk's link is probably the most descriptive. Essentially you've defined a function that reads `i`, but only does so at runtime. What `i` is at time of definition is unimportant. If you move the assignment `i=i` into the `def` statement, then Python will intern that value as the local `i` (since the whole `def` line gets executed at definition time, not at run time) – Adam Smith Oct 18 '15 at 05:22
  • @AdamSmith: The link's examples ares somewhat different from mine. In the first example, f() is called after the for loop, which makes sense because funcs.append(lambda: x) would then call the value x which is at this time, 3. But in my example, i is called during the for loop, not after it, therefore it doens't make sense for i to be 9 all the time. This is what confuses me. I think this question deserves to be answered in it's own right. – Dang Manh Truong Oct 18 '15 at 08:24
  • @TruongTroll I agree that the question this got duped to isn't the best example, but if you read [the link](http://stackoverflow.com/questions/19837486/python-lambda-in-a-loop) that Tigerhawk left then it explains it succinctly. It builds a lambda in a `for` loop that accesses the incrementing variable. Again it's because the your `i` (and their `d`) is never read DURING the loop, only when the function is called. It would actually surprise me if this doesn't throw a `NameError` in Python3. – Adam Smith Oct 18 '15 at 17:03
  • @AdamSmith Smith How come "i" is not read during the loop ?? It is very clear in the example that UI.Button("button %s" % i, callback) is indented more than the for statement, therefore it must be in the loop. And i think having lambda as an example may be confusing to readers, so a new question would be most appropriate – Dang Manh Truong Oct 19 '15 at 11:06
  • @TruongTroll because a function's body is not read until that function is called. This code never calls the function, it just references it (e.g. you use `callback` not `callback(i)`). – Adam Smith Oct 19 '15 at 14:35
  • @TruongTroll the function isn't called until you press the button, which is well after the `for` loop finishes – Adam Smith Oct 19 '15 at 14:36
  • @AdamSmith Now I understand, thank you very much – Dang Manh Truong Oct 25 '15 at 16:35

0 Answers0