循环中修改按钮command参数时索引值统一为最终值的解决方法
问题原因
你遇到的是Python闭包的常见陷阱:lambda表达式捕获的是变量引用,而非循环时的具体值。循环结束后,index变量最终变成12,所有按钮点击时都会调用这个最终值,导致所有按钮都用12作为参数。另外注意你的dd_coords键是1-12,但循环里的index是0-11,就算解决闭包问题,也要把index加1才能匹配字典的键。
解决方法
方法1:用lambda默认参数绑定当前值
修改set_vector方法里的lambda,给它加一个默认参数,把循环时的index值绑定进去:
def set_vector(self): index = 0 for items in self.airfields_btn: # 用默认参数idx绑定当前index的值,同时+1匹配dd_coords的键 items.config(command = lambda idx=index: self.get_location(idx + 1)) index += 1
默认参数会在定义lambda时就把当前index的值存下来,而不是等到调用时再去取变量的引用。
方法2:用functools.partial绑定参数
functools.partial可以直接帮你把参数预先绑定到函数上,写法更清晰:
先导入functools:
import functools
然后修改set_vector方法:
def set_vector(self): index = 0 for items in self.airfields_btn: items.config(command = functools.partial(self.get_location, index + 1)) index += 1
partial会创建一个新的函数,把index+1作为固定参数传给get_location,避免闭包引用的问题。
额外优化:遍历同时获取索引
可以用enumerate直接获取循环的索引,不用手动维护index变量,代码更简洁:
def set_vector(self): for idx, items in enumerate(self.airfields_btn): items.config(command = lambda i=idx: self.get_location(i + 1))
内容的提问来源于stack exchange,提问作者golem
相关产品推荐
相关产品推荐

