lambda (and reduce) are valuable

Bengt Richter bokr at oz.net
Mon Dec 12 12:13:29 CET 2005


On Mon, 12 Dec 2005 09:15:38 +0100, "Fredrik Lundh" <fredrik at pythonware.com> wrote:

>Steven Bethard wrote:
>
>> > I thought stuff like the following was idiomatic in GUI programming.
>> > Do you really want separate names for all those callbacks?
>> >
>> > # generate calculator keypad buttons
>> > Button(label='7', command=lambda: user_pressed(7)).grid(column=1, row=1)
>> > Button(label='8', command=lambda: user_pressed(8)).grid(column=2, row=1)
>> > Button(label='9', command=lambda: user_pressed(9)).grid(column=3, row=1)
>> >
>> > Button(label='4', command=lambda: user_pressed(4)).grid(column=1, row=2)
>> > Button(label='5', command=lambda: user_pressed(5)).grid(column=2, row=2)
>> > Button(label='6', command=lambda: user_pressed(6)).grid(column=3, row=2)
>> > ...
>>
>> While I don't spend much time on GUIs, code like that would scream
>> "refactor" to me, e.g. something like:
>>
>> class UserPressedButton(Button):
>>      def __init__(self, i):
>>          def command():
>>              return user_pressed(i)
>>          Button.__init__(self, label=str(i), command=command)
>>
>> Button(7).grid(column=1, row=1)
>> Button(8).grid(column=2, row=1)
>> Button(9).grid(column=3, row=1)
>>
>> Button(4).grid(column=1, row=2)
>> Button(5).grid(column=2, row=2)
>> Button(6).grid(column=3, row=2)
>
>a temporary factory function should be sufficient:
>
>    def digit(label, x, y):
>        def callback():
>            # print "BUTTON PRESS", label # debug!
>            user_pressed(int(label))
>        Button(label=label, command=callback).grid(column=x, row=y)
>
>    # create numeric pad
>    digit("7", 1, 1); digit("8", 2, 1); digit("9", 3, 1)
>    digit("4", 1, 2); digit("5", 2, 2); digit("6", 3, 2)
>    digit("1", 1, 3); digit("2", 2, 3); digit("3", 3, 3)
>
>are people still missing that local functions are inexpensive in Python ?

OTOH, (untested)

    for label, x, y in ((str(d+1), d%3+1, 3-d//3) for d in xrange(9)):
        Button(label=label, command=lambda d=int(label):user_pressed(d)).grid(column=x, row=y)

or

    for tup in ((str(d+1), d%3+1,3-d//3) for d in xrange(9)): digit(*tup)

tweak 'til correct ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list