Python作业
Python Homework
我一直在写一个记录作业的软件,用python写的。我会给出一个显示所有作业的小片段。
def delHomework(homework,element,HLabel,HDelete):
del homework.get(element)
HLabel.destroy()
HDelete.destroy()
row = 0 #keeps track on which height everything is inserted
for i in homeworks: #homeworks is a list of all homework's
HLabel = Label(text=i) #displays the homework
HLabel.grid(column=0,row=row)
HDelete = Button(text="delete",command=lambda:
delHomework(homework,i,HLabel,HDelete)
#is the button to delete the homework
HDelete.grid(column=1,row=row)
row += 1
问题是,即使它全部显示正确,当您尝试删除任何作业时,最后一个作业被删除而不是关联的作业,因为 lambda 在该迭代中引用的是变量的最新状态,而我可以弄清楚如何让它发挥作用。希望这个问题有道理。
假设 HDelete
的括号缺失只是复制粘贴问题。
实际问题是,在函数被调用之前,不会为 lambda 函数计算 i
的值,当它被调用时,它使用 i
的最新值,在这种情况下,这将是 homworks
列表中 i
的最后一个值。
一个非常简单的例子-
>>> lst = [1,2,3,4,5,6]
>>> newlst = []
>>> for i in lst:
... newlst.append(lambda : print(i))
...
>>> newlst[1]()
6
>>> newlst[2]()
6
您应该将元素作为默认参数传递给 lambda
。示例 -
HDelete = Button(text="delete",command=lambda ele = i, hl = HLabel, hd = HDelete:
delHomework(homework,ele,hl,hd))
Example/Demo 展示它的工作原理 -
>>> lst = [1,2,3,4,5,6]
>>> newlst = []
>>> for i in lst:
... newlst.append(lambda ele = i: print(ele))
...
>>> newlst[2]()
3
>>> newlst[1]()
2
如以下问题的已接受答案中所述:What do (lambda) function closures capture?
你可以这样做:
HDelete = Button(text="delete",command=(lambda i, l, d: lambda:
delHomework(homeworks, i, l, d))(i, HLabel, HDelete)
或类似这样的内容:
def createDeleteCommand(homeworks, i, l, d):
return lambda: delHomework(homeworks, i, l, d)
HDelete = Button(text="delete",command=
createDeleteCommand(homeworks, i, HLabel, HDelete))
我一直在写一个记录作业的软件,用python写的。我会给出一个显示所有作业的小片段。
def delHomework(homework,element,HLabel,HDelete):
del homework.get(element)
HLabel.destroy()
HDelete.destroy()
row = 0 #keeps track on which height everything is inserted
for i in homeworks: #homeworks is a list of all homework's
HLabel = Label(text=i) #displays the homework
HLabel.grid(column=0,row=row)
HDelete = Button(text="delete",command=lambda:
delHomework(homework,i,HLabel,HDelete)
#is the button to delete the homework
HDelete.grid(column=1,row=row)
row += 1
问题是,即使它全部显示正确,当您尝试删除任何作业时,最后一个作业被删除而不是关联的作业,因为 lambda 在该迭代中引用的是变量的最新状态,而我可以弄清楚如何让它发挥作用。希望这个问题有道理。
假设 HDelete
的括号缺失只是复制粘贴问题。
实际问题是,在函数被调用之前,不会为 lambda 函数计算 i
的值,当它被调用时,它使用 i
的最新值,在这种情况下,这将是 homworks
列表中 i
的最后一个值。
一个非常简单的例子-
>>> lst = [1,2,3,4,5,6]
>>> newlst = []
>>> for i in lst:
... newlst.append(lambda : print(i))
...
>>> newlst[1]()
6
>>> newlst[2]()
6
您应该将元素作为默认参数传递给 lambda
。示例 -
HDelete = Button(text="delete",command=lambda ele = i, hl = HLabel, hd = HDelete:
delHomework(homework,ele,hl,hd))
Example/Demo 展示它的工作原理 -
>>> lst = [1,2,3,4,5,6]
>>> newlst = []
>>> for i in lst:
... newlst.append(lambda ele = i: print(ele))
...
>>> newlst[2]()
3
>>> newlst[1]()
2
如以下问题的已接受答案中所述:What do (lambda) function closures capture?
你可以这样做:
HDelete = Button(text="delete",command=(lambda i, l, d: lambda:
delHomework(homeworks, i, l, d))(i, HLabel, HDelete)
或类似这样的内容:
def createDeleteCommand(homeworks, i, l, d):
return lambda: delHomework(homeworks, i, l, d)
HDelete = Button(text="delete",command=
createDeleteCommand(homeworks, i, HLabel, HDelete))