Lambdas and variables
James Henderson
james at logicalprogression.net
Thu Jul 29 07:23:04 EDT 2004
John Fouhy wrote:
> [original post: http://groups.google.co.nz/groups?hl=en&lr=&ie=UTF-8&selm=c0f3aa87.0407271535.40217366%40posting.google.com
> ]
>
> Derek Thomson <derek.thomson at gmail.com> wrote in message news:<mailman.861.1090973013.5135.python-list at python.org>...
>
>>It's to do with the environment to which a function, or a lambda, is
>>bound. "x" in the lambda will always refer to the x defined in the
>>enclosing scope, and you last left that set to "zof".
>
> Ok, so when I write 'lambda e: printSomething(x)', that creates a
> function which, when called, will look up the value of the variable
> 'x', and then call printSomething on that value. And that value will
> be whatever x was last set to. Is that correct?
That's right, and it's an example of "Python's general late-binding
semantics", which came under so much discussion recently with respect to
generator expressions. See:
http://mail.python.org/pipermail/python-dev/2004-April/044555.html
and the surrounding threads.
> What if I do 'lambda e: printSomething(copy.deepcopy(x))'? That
> creates a function which, when called, will look up the value of 'x',
> make a deep copy, and then call printSomething on it?
>
> ('cos that doesn't work either)
The copying won't be done till the function is called and you will still
get whatever x was last set to in the lexical scope. But I see you're
trying to associate a piece of data with a function - to create a sort
of closure - and that's exactly where the default argument trick comes
in. Default arguments can be used for this effect since they freeze the
value at the time of the function's definition.
> If what I wrote is correct, then I think I understand now. And I will
> use the change James Henderson suggested. But it definitely feels
> like a gotcha if I can't replace a function that just does 'return X'
> with 'X' itself.
I agree it's a gotcha. Interestingly you would have been forced to pass
x in as a default argument and avoided your problem until Python
introduced nested scopes in versions 2.1 and 2.2. You may find PEP 227
on statically nested scopes illuminating:
http://www.python.org/peps/pep-0227.html
James
More information about the Python-list
mailing list