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