gpt4 book ai didi

python - for循环中的lambda仅取最后一个值

转载 作者:太空宇宙 更新时间:2023-11-03 20:34:40 25 4
gpt4 key购买 nike

问题:

上下文菜单应动态显示过滤器变量,并使用回调中定义的参数执行函数。一般描述正确显示,但函数调用始终使用最后设置的选项执行。

我尝试过的:

#!/usr/bin/env python

import Tkinter as tk
import ttk
from TkTreectrl import MultiListbox

class SomeClass(ttk.Frame):
def __init__(self, *args, **kwargs):
ttk.Frame.__init__(self, *args, **kwargs)
self.pack(expand=True, fill=tk.BOTH)

self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)

self.View=MultiListbox(self)

__columns=("Date","Time","Type","File","Line","-","Function","Message")
self.View.configure(columns=__columns, expandcolumns=(0,0,0,0,0,0,0,1))

self.View.bind("", self.cell_context)
self.View.grid(row=0, column=0, sticky=tk.NW+tk.SE)

self.__recordset = []
self.__recordset_filtered = False

#Some dummy values
self.__recordset.append(["Date", "Time", "INFO", "File", "12", "-", "Function", "Message Info"])
self.__recordset.append(["Date", "Time", "DEBUG", "File", "12", "-", "Function", "Message Info"])
self.__recordset.append(["Date", "Time", "WARNING", "File", "12", "-", "Function", "Message Info"])

self.__refresh()

def cleanView(self):
self.View.delete(0, tk.END)

def __refresh(self):
self.cleanView()
for row in self.__recordset:
self.View.insert(tk.END, *row)

def filter_records(self, column, value):
print("Filter Log Recordset by {column} and {value}".format(**locals()))
# Filter functionality works as expected
# [...]

def cell_context(self, event):
__cMenu=tk.Menu(self, tearoff=0)

if self.__recordset_filtered:
__cMenu.add_command(label="Show all", command=lambda: filter_records(0, ""))

else:
column=2
options=["INFO", "WARNING", "DEBUG"]

for i in range(len(options)):
option=options[i]
__cMenu.add_command(label="{}".format(option), command=lambda: self.filter_records(column, option))
# Also tried using for option in options here with same result as now
__cMenu.post(event.x_root, event.y_root)

if __name__=="__main__":
root=tk.Tk()
app=SomeClass(root)
root.mainloop()

我得到的当前输出是:

Filter Log Recordset by 2 and DEBUG

无论我选择三个选项中的哪一个。我认为它与垃圾收集有关,只剩下最后一个选项,但我不知道如何避免这种情况。

建议提供任何帮助。

最佳答案

请阅读 minimal examples 。在不阅读您的代码的情况下,我相信您已经遇到了之前的问题和答案中解决的一个众所周知的问题,需要两行来说明。函数体中的名称在函数执行时进行评估。

funcs = [lambda: i for i in range(3)]
for f in funcs: print(f())

打印 '2' 3 次,因为这 3 个函数是相同的,并且每个函数中的 'i' 直到调用(当 i == 2 时)才会计算。但是,

funcs = [lambda i=i:i for i in range(3)]
for f in funcs: print(f())

创建三个不同的函数,每个函数都有不同的捕获值,因此会打印 0、1 和 2。在你的声明中

__cMenu.add_command(label="{}".format(option),
command=lambda: self.filter_records(column, option))

:之前添加option=option以捕获option的不同值。您可能想重写为

lambda opt=option: self.filter_records(column, opt)

区分循环变量和函数参数。如果column在循环内发生变化,则需要相同的处理。

关于python - for循环中的lambda仅取最后一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57243048/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com