newbie: binding args in callbacks

Alex Martelli aleax at aleax.it
Wed Jul 10 11:14:29 EDT 2002


Edward K. Ream wrote:
        ...
>>     def makeCallback(self, val):
>>         def callback(): return self.myCallback(val)
>>         return callback
> 
> I tried this, and indeed this does work on 2.2. Really.  Thanks very
> much.

You're welcome!


> This "extra" level of indirection is needed. The following does not
> work:
> 
> for val in vals:
>   callback=lambda: self.myCallback(val) # or (val=val)
>    b = Tk.Button(..., command=callback)
> 
> All the callbacks get bound to a function with the last val in vals.  I
> have no idea why.  Maybe you could explain?

Sure.  You need to "snapshot" the value of val at the moment you're
interested in it -- passing it as an argument is one way to do that.

In the for loop that you show, the use of val in:
   callback=lambda: self.myCallback(val)
indicates the variable thus named in outer scope (or global scope),
and the relevant value is the one that said variable has _when
the lambda is later called_ -- by what time the loop has proceeded
to the end and val has stayed bound to the last value.

BTW, the for loop using:

   callback = lambda val=val: self.myCallback(val)

should work just fine -- now you're "snapshotting" again (passing
val as an argument, so the value that matters is here the one at
*function-definition* time, as in the "extra level of indirection"
case that I suggest, NOT the value at *function-call* time in the
outer or global scope).

I consider the use of makeCallback preferable for stylistic reasons,
although it does also have the desired snapshot effect -- the latter
could also be obtained in other ways.


> BTW, the reason I really like Python is that someone like me with
> limited knowledge can actually produce some real work.  Anyway, thanks
> again for your help!

Again you're welcome, and I share your evaluation of Python -- a full
grasp of the nicer points helps, but for 99% of one's work one can
do almost as well without it!-)


Alex




More information about the Python-list mailing list