Lambdas and variables

James Henderson james at logicalprogression.net
Thu Jul 29 13:23:04 CEST 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