problem with tk and pass by refference (I think :)

Discussion in 'Python' started by Matthew Thorley, Feb 11, 2005.

  1. Greetings, Maybe someone out there can lend me an eye? I've been
    stumped, banging my head against the wall trying to figure out why my
    script doesn't work. I've tried every thing I could think of, even
    unecessarily complicated mumbo-jumbo. Let me show you a snippet and then
    I'll explain what's happening.


    for verse in self.activeSong['verses']:
    verseNum = self.activeSong['verses'].index(verse)
    activeSong = self.activeSong.copy()
    firstLine = split(verse, '\n')[0]
    button = Button(self.songWin, text=verse, command=(lambda:
    self.showVerse(verseNum)) )
    button.config(bg='grey')
    button.pack(expand=YES, fill=BOTH, side=TOP)
    self.verseButtons.append(button)


    This is as simple app for displaying the words of a song with an
    overhead projector. When you click on a song the program reads it and
    creates a button for each verse. When you click the button it is
    supposed to display that verse. As you can see above I am trying to call
    the showVerse method and pass it the verseNum.

    The problem I am having is that every button gets assigned the verseNum
    for the last verse that gets processed. That is to say, if a sone has 4
    verses every button shows verse for, a 6 verse song loads verse 6 for
    every button, etc. I think that the value is getting passed by
    reference, so it gets updated with every iteration. I have seriously
    tried every thing I can think of to fix this.

    If any one has any thoughts I would really appreciate it.
    Thanks very much!
    -Matthew
    Matthew Thorley, Feb 11, 2005
    #1
    1. Advertising

  2. Hi,

    button = Button(self.songWin, text=verse, command=(lambda num=verseNum:
    self.showVerse(num)) )

    should do the trick. The reason is basically that your version kept a
    reference to verseNum - and when executed, the value verseNum points to is
    the lasts one stored.

    Rebinding the argument to a parameter in the lambda will keep the right
    value for each iteration.


    --
    Regards,

    Diez B. Roggisch
    Diez B. Roggisch, Feb 11, 2005
    #2
    1. Advertising

  3. Diez B. Roggisch wrote:
    > Hi,
    >
    > button = Button(self.songWin, text=verse, command=(lambda num=verseNum:
    > self.showVerse(num)) )
    >
    > should do the trick. The reason is basically that your version kept a
    > reference to verseNum - and when executed, the value verseNum points to is
    > the lasts one stored.
    >
    > Rebinding the argument to a parameter in the lambda will keep the right
    > value for each iteration.
    >
    >

    I tried it but I got a syntax error. The interpreter didn't like the
    equals sign in the lambda. I am using python 2.3.4. Is there another way
    of writing that?

    thanks
    Matthew Thorley, Feb 11, 2005
    #3
  4. > I tried it but I got a syntax error. The interpreter didn't like the
    > equals sign in the lambda. I am using python 2.3.4. Is there another way
    > of writing that?


    Strange. This script works and shows the desired behaviour - python is also
    2.3.4:

    def foo(x):
    print x


    fs = [lambda: foo(i) for i in xrange(5)]
    for f in fs:
    f()

    fs = [lambda x=i: foo(x) for i in xrange(5)]
    for f in fs:
    f()


    --
    Regards,

    Diez B. Roggisch
    Diez B. Roggisch, Feb 11, 2005
    #4
  5. Diez B. Roggisch wrote:
    >>I tried it but I got a syntax error. The interpreter didn't like the
    >>equals sign in the lambda. I am using python 2.3.4. Is there another way
    >>of writing that?

    >
    >
    > Strange. This script works and shows the desired behaviour - python is also
    > 2.3.4:
    >
    > def foo(x):
    > print x
    >
    >
    > fs = [lambda: foo(i) for i in xrange(5)]
    > for f in fs:
    > f()
    >
    > fs = [lambda x=i: foo(x) for i in xrange(5)]
    > for f in fs:
    > f()
    >
    >

    You're right! It was my fault. I left the colon after the lambda by
    mistake. e.g. lambda: num=verseNum:...

    Thanks very much for the help it works great now! I wish I would have
    asked somebody sooner :)
    -Matthew
    Matthew Thorley, Feb 11, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ec
    Replies:
    3
    Views:
    462
    Pascal Peyremorte
    Nov 21, 2006
  2. Replies:
    0
    Views:
    582
  3. Yankee Imperialist Dog!

    server transfer and previous page refference issue

    Yankee Imperialist Dog!, Apr 25, 2009, in forum: ASP .Net
    Replies:
    2
    Views:
    1,025
    Yankee Imperialist Dog!
    Apr 25, 2009
  4. Tim

    Refference my current frame

    Tim, Mar 14, 2005, in forum: Javascript
    Replies:
    0
    Views:
    91
  5. Lae.
    Replies:
    7
    Views:
    88
    Dennis Ă…lund
    Dec 11, 2005
Loading...

Share This Page