Parameterized functions of no arguments?
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Fri Feb 11 03:19:00 EST 2011
On Fri, 11 Feb 2011 06:32:56 +0000, Rotwang wrote:
> I don't understand why this works. What is the difference between
>
> (lambda x: lambda: f(x))(k)
>
> and
>
> lambda: f(k)
>
> ?
Re-writing them as normal function defs may help. I'm going to do them in
reverse order:
# lambda: f(k)
def func():
return f(k)
When you call func() with no arguments, the body is executed and f(k) is
returned. Where do f and k come from? At runtime, Python searches the
local namespace of func(), and doesn't find either f or k. It then
searches the non-local namespace, that is, the function or method that
surrounds func (or your lambda), if any. In your case, there is no such
nested function, so finally it searches the global namespace, and finds
both f and k. But by the time the function is called, the for-loop which
sets k has reached the end, and k always has the same value.
# (lambda x: lambda: f(x))(k)
def func(x):
def inner():
return f(x)
return inner
When you call func(k), it creates a nested function. That nested function
includes a "closure", which is a copy of the namespace of func at the
time it is called. This closure includes a variable "k".
That inner function is returned and saved as the callback function. When
you call that callback function, it executes inner(), and f(k) is
returned. Where do f and k come from? As normal, Python searches the
local namespace, and doesn't find them, but then it finds the variable k
in the closure, and *not* the global k that the earlier example would
find.
This example may help:
store = []
for k in range(3):
fa = lambda: "k has the value %d" % k
fb = (lambda x: lambda: "x has the value %d" % x)(k)
print("fa inside the loop", fa())
print("fb inside the loop", fb())
store.append(fa)
store.append(fb)
for func in store:
print("func outside the loop", func())
del k
store[1]() # one of the closures
store[0]() # one of the non-closures
Hope this helps.
--
Steven
More information about the Python-list
mailing list