[Python-Dev] 2.5 and beyond

Giovanni Bajo rasky at develer.com
Sat Jul 1 03:43:01 CEST 2006


[Giovanni Bajo]
> Yes but:
>
>>>> a = []
>>>> for i in range(10):
> ...     a.append(lambda: i)
> ...
>>>> print [x() for x in a]
> [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
>
> This subtle semantic of lambda is quite confusing, and still forces people to
> use the "i=i" trick.

[Tim Peters]
> So stay away from excruciating abuses of lexical scoping you don't
> understand   What do you expect `i` to refer to?  "Oh, it should
> guess that I didn't really mean to defer evaluation of the lambda body
> at all, but instead evaluate the lambda body at the time I define the
> lambda and then synthesize some other function that captures the
> specific outer bindings in effect at lambda-definition time" doesn't
> really cut it.

I think I understand what happens, I just don't know whether this can be
"fixed" or not. Unless you are saying that the above behaviour is not only a
complex side-effect the way things are, but the way things should be. Do you
agree that it would be ideal if the above code generated range(10) instead of
[9]*10, or you believe that the current behaviour is more sound (and if so,
why)?

As for actual implementing this change of semantic, the fact that `i` is a
local variable in the outer scope (assuming it's all within a function),
doesn't make it possible for Python to early-bound it, by realizing that, since
`i` is not an argument of the lambda, and it's a local of the outer scope? At
worse, couldn't Python do the "i=i" trick by itself when it sees that `i` is a
local in the outer scope? Right now I can't think off-hand of a case in which
this would break things.

[Tim Peters]
> This isn't typical use for lambda,


Yes, maybe it's not the most used idiom and Andrew wasn't referring to this,
but it happens quite often to me (where 'often' means 'many times' among my
rare usages of lambda).

For instance, in GUI code, it's common to do things like:

for b in self.buttons:
     self.setEventCallback(b, "clicked", lambda: self.label.setText("I pressed
button %r" % b))

... which of course won't work, as written above.

Giovanni Bajo
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/gif
Size: 135 bytes
Desc: not available
Url : http://mail.python.org/pipermail/python-dev/attachments/20060701/ebb3a2b4/attachment.gif 


More information about the Python-Dev mailing list