Python作业

标签 python closures

我一直在写一个用 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))

展示其工作原理的示例/演示 -

>>> 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

关于Python作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32316845/

相关文章:

python - lambda排序列表奇怪的行为

javascript - 尝试用 JavaScript 创建非常简单的闭包

python - Python 中的闭包

r - 环境、(en)closures 和框架是如何相关的?

Python - 合并列表中的一行列表

python - 是否可以创建一个既没有 __slots__ 也没有 __dict__ 的 python 对象?

python - 如何使用 django-authopenid 设置默认组?

python - TorchScript 需要源代码访问才能对 collections.deque 进行编译

JavaScript 闭包,只是没有得到它

php - 在闭包函数参数PHP中添加类-引发未捕获的TypeError