[Python-ideas] For loop binding (was Re: Tweaking closures ...)
Terry Reedy
tjreedy at udel.edu
Tue Sep 27 23:10:27 CEST 2011
On 9/27/2011 1:05 AM, Greg Ewing wrote:
>
> For example, when someone writes
>
> for i in things:
> def f():
> dosomethingwith(i)
> squirrelaway(f)
>
> and get surprised by the result,
People who post their 'surprise' on python-list have nearly always used
lambda, not def, to define the function. This is so much the case that I
have concluded that 'lambda' has a hypnotic effect that 'def' does not.
> he's effectively assuming that the for-loop creates a new binding for
> i each time around.
No, for loops *do* rebind loop variables each time around. People are
assuming that 'i' is immediately bound to its 'current' value, just like
default args. (This is the opposite of people who mis-assume that
default arg expressions are re-evaluated with each call.) This
assumption is tied much more to 'lambda' than 'def'.
> He may not *realise* he's assuming that, but he is.
>
> Given that people seem to unconsciously make that
> assumption,
*Some* people -- those who come from a language that does whatever it is
that python does not do that you want it to do.
> perhaps we should consider making the
> for-loop actually behave that way. There's a precedent
> for this -- list comprehensions used to leak their
> loop variable into the surrounding scope, but that
> was eventually changed.
This has *nothing* to do with people assuming early binding of names in
lambda expressions. The posted 'surprise code' typically uses list
comps. So changing for loops to be like list comps would have no effect
on that mis-assumptions and the resulting surprise.
--
Terry Jan Reedy
More information about the Python-ideas
mailing list