2013-02-20 102 views
2

第一篇文章在这里。Lambda意外地评估

我想制作一个电影列表。电影将显示在Tkinter的列表中。该计划是当您点击更新按钮时,程序将更新旁边的标签。问题在于无论您点击哪个按钮,都会更新最后一个标签。我想这是因为

lambda: self.update_rating(x)

在运行时计算,所以为x。我希望x是它在特定循环上的内容,而不是按钮被点击时的范围之外的内容。

我是新来的蟒蛇所以任何帮助表示赞赏

代码:

from Tkinter import * 
class Application(Frame): 
    def __init__(self, master): 
     Frame.__init__(self, master) 
     self.grid() 
     self.create_widgets() 
    def create_widgets(self): 
     self.movies = list() 
     for x in range(0, 10): 
      movie = list() 
      rating = Label(self, text = "Rating: NA") 
      rating.grid(row = x, column = 0, columnspan = 1, sticky = W) 
      movie.append(rating) 
      update = Button(self, text = "update", command = lambda: self.update_rating(x)) 
      update.grid(row = x, column = 1, columnspan = 1, sticky = W) 
      movie.append(update) 
      self.movies.append(movie) 
    def update_rating(self, num): 
     self.movies[num][0]["text"] = "rating updated" 
root = Tk() 
root.title("Movie Sorter") 
root.geometry("640x480") 
app = Application(root) 
root.mainloop() 

回答

2

用这个代替:

lambda x=x: self.update_rating(x) 

示范:

>>> x = 1 
>>> a = lambda x=x:x 
>>> a() 
1 
>>> x = 2 
>>> a() 
1 

这里的想法是默认的当功能是定义为而不是创建一个闭包,当功能是,称为时,创建一个闭包,该闭包评估从封闭范围中拾取变量。

+0

谢谢,我被困在这太久了。 – Henry 2013-02-20 12:54:34

+2

@亨利 - 这是一个常见问题。 – mgilson 2013-02-20 12:55:26