newbie: binding args in callbacks
Alex Martelli
aleax at aleax.it
Wed Jul 10 10:29:01 EDT 2002
Edward K. Ream wrote:
> This question was asked a while back, and I don't see it in the FAQ or
> in the archives...
>
> I would like to create a set of Tkinter callbacks that vary only in the
> bindings of a single argument. For example, I would like to do:
>
> for val in vals:
> b = Tk.Button(...,command=self.myCallback(val))
>
> But this doesn't work: it executes callback, rather than returning the
> callback function with the second arg bound to val.
Right.
> I also tried:
>
> for val in vals:
> callback=lambda None:self.myCallback(x=val)
> b = Tk.Button(...,command=callback)
>
> But that doesn't quite work either. When the callback executes I get:
> TypeError: <lambda>() takes exactly 1 argument (0 given)
Indeed, you specified a lambda taking a single argument (accidentally
named None just like the popular builtin object) and ignoring it.
> Can someone explain how to do this? Thanks.
My suggestion:
def makeCallback(self, val):
def callback(self=self, val=val): return self.myCallback(val)
return callback
and then:
b = Tk.Button(..., command=self.makeCallback(val) )
You don't need the default-values trick in Python 2.2 -- so, if
that's what you're using, it would be better to use, instead:
def makeCallback(self, val):
def callback(): return self.myCallback(val)
return callback
If you're insistent on using lambda (only sensible reason being that
you made a bet about lambda being used here), you _can_, e.g. in 2.2:
def makeCallback(self, val):
return lambda: self.myCallback(val)
but I think the nested-function approach is more readable.
Alex
More information about the Python-list
mailing list