Using Lambda Function in Loop Gives Wrong Input Value

I don’t think your diagnosis is correct – the lambda is working
correctly. The issue is that you are NOT binding the event to any
one specific button here. You are simply making two identical calls
to self.Bind, each of which will handle ALL buttons. Pressing
EITHER button will trigger BOTH events.
If you need to identify the button, the easiest way is to store an
identifier in the button object.
for i in range(0,2):
currButton = …
currButton.MyOrdinal = i
self.Bind( wx.EVT_BUTTON, self.ButtonFunc, currButton )
def cButtonFunc( self, event ):
cNum = event.GetEventObject().MyOrdinal

···

Kayla DesPortes wrote:

    I am currently running into an

issue using the lambda function and the partial function in a
loop. Code Below:

for i in range(0,2):
currButton =
gb.GradientButton(panel,label="C Agent
"+str(i),pos=(locX,locY),size=(block,block))

        self.Bind(wx.EVT_BUTTON,lambda

event, cNum=i: self.cButtonFunc(event,cNum))

-- Tim Roberts, Providenza & Boekelheide, Inc.

timr@probo.com

Kayla DesPortes wrote:

I am currently running into an issue using the lambda function and the
partial function in a loop. Code Below:
...
                for i in range(0,2):
                        currButton = gb.GradientButton(panel,label="C Agent
"+str(i),pos=(locX,locY),size=(block,block))
                        self.Bind(wx.EVT_BUTTON,lambda event, cNum=i:
self.cButtonFunc(event,cNum))

I don't think your diagnosis is correct -- the lambda is working correctly.
The issue is that you are NOT binding the event to any one specific button
here. You are simply making two identical calls to self.Bind, each of which
will handle ALL buttons. Pressing EITHER button will trigger BOTH events.

Oops, good call. self.Bind(wx.EVT_FOO) will claim all FOO events of that type.

If you need to identify the button, the easiest way is to store an
identifier in the button object.

Or he could use his current system, but use button.Bind instead of
self.Bind. That seems preferable to monkey-patching a new field into
the button object:

for i in xrange(2):
    button = ...
    button.Bind(wx.EVT_BUTTON, lambda cNum = i: self.buttonFunc(cNum))

--
Tim Roberts, timr@probo.com

-Chris

···

On Wed, Sep 26, 2012 at 10:50 AM, Tim Roberts <timr@probo.com> wrote:

And this may help Kayla or others understand why: self.Bind vs. self.button.Bind - wxPyWiki

···

On 9/26/12 10:56 AM, Chris Weisiger wrote:

On Wed, Sep 26, 2012 at 10:50 AM, Tim Roberts <timr@probo.com> wrote:

Kayla DesPortes wrote:

I am currently running into an issue using the lambda function and the
partial function in a loop. Code Below:
...
                 for i in range(0,2):
                         currButton = gb.GradientButton(panel,label="C Agent
"+str(i),pos=(locX,locY),size=(block,block))
                         self.Bind(wx.EVT_BUTTON,lambda event, cNum=i:
self.cButtonFunc(event,cNum))

I don't think your diagnosis is correct -- the lambda is working correctly.
The issue is that you are NOT binding the event to any one specific button
here. You are simply making two identical calls to self.Bind, each of which
will handle ALL buttons. Pressing EITHER button will trigger BOTH events.

Oops, good call. self.Bind(wx.EVT_FOO) will claim all FOO events of that type.

If you need to identify the button, the easiest way is to store an
identifier in the button object.

Or he could use his current system, but use button.Bind instead of
self.Bind. That seems preferable to monkey-patching a new field into
the button object:

for i in xrange(2):
     button = ...
     button.Bind(wx.EVT_BUTTON, lambda cNum = i: self.buttonFunc(cNum))

--
Robin Dunn
Software Craftsman