Question on lambdas

Thomas Rachel nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915 at spamschutz.glglgl.de
Tue Dec 9 05:46:28 EST 2014


Am 09.12.2014 04:09 schrieb memilanuk:

> so in the first example in my original post:
>
> ...
> lambda: update_label2('A', 100)
>
> would this work the same?  It looks as though it'd be passing the same
> two parameters to the same function...
>
> lambda: 'A', 100: update_label2()

No. Even if it would be allowed by syntax, how should 'A', 100 be passed 
to update_label2() if it is not written inside its ()s?

> Also, in my second example:
>
> class MyText(Text):
>      def __init__(self, master, **kw):
>          apply(Text.__init__, (self, master), kw)
>          self.bind("<Return>", lambda e: "break")
>
> I'm kind of missing what 'e' is and where its defined and what it's
> supposed to be passing to "break"...?

Passing to "break"? A string cannot be passed anything.

What bind() expects is any callable which takes an event object (IIRC).

As you don't need any information from the event object here, you can 
ignore it (but it must be oresent, otherwise the call would fail).

What the function does is just return "break". What sense this should 
have is unclear to me; probably the return value is just ignored.


> I was reading in 'Programming Python 4th ed' by Lutz and he talks about
> something to do with default values vs. enclosing scopes...  that
> something like:
>
> lambda x=x: some_expr
>
> when evaluated inside a function loop to create buttons, etc., causes
> 'x' to be evaluated as the default value at the function creation time,
> vs. when the function is actually called.  Do I have that more or less
> correct?

Yes. This one takes the current value of x inside the function.

Compare these:

x = 4
f1 = lambda: x
x = 5
f2 = lambda: x
x = 42
print f1(), f2()

What could one expect? "4 5", maybe. What does one get? "42 42". Why? 
Because the x is evaluated at the time it is indeed called.

We can work around this with

x = 4
f1 = lambda y=x: y
x = 5
f2 = lambda y=x: y
x = 42
print f1(), f2()

(you can take x for y here, but this one is better understandable)

Here each of the function gets the respective value "tattooed in"; we 
get "4 5" indeed as output.

Downside is that we have the possibility to do print f1(123) which 
indeed gives 123.

If we want to disallow this kind of calls, we could do

def create_const_function(val):
     def inner_function():
         return val

or just

create_const_function = lambda val: lambda: val

and then

f1 = create_const_function(4)
f2 = create_const_function(5)
print f1(), f2()

et voilà.


Thomas



More information about the Python-list mailing list