Python循环生成带lambda的字典时所有条目均绑定最后一个对象问题求助
问题原因
这是Python闭包的延迟绑定特性导致的问题:
- lambda函数属于闭包,内部引用的变量
obj不会在lambda定义阶段就保存当前值,只会在lambda实际被调用时,才会查找obj的当前取值 - 遍历
stuff.instances的循环结束后,obj变量最终指向列表的最后一个实例,因此所有菜单条目对应的lambda被触发时,传入buy函数的都是最后一个实例 - 你之前测试直接输出
obj.name可以得到正确值,是因为取值动作发生在循环执行过程中,不是等循环结束后通过lambda调用,因此不会触发该问题
修复方案
只需要修改你标注的有问题的那行代码,通过lambda的默认参数把当前迭代的obj值固定下来即可:Python中函数的默认参数会在函数定义阶段完成求值并保存,刚好可以规避延迟绑定的问题。
修改前的代码:
stock[f"{obj.name:<10} {obj.qty:<5} ${obj.price}"] = lambda: buy(obj)
修改后的代码:
stock[f"{obj.name:<10} {obj.qty:<5} ${obj.price}"] = lambda obj=obj: buy(obj)
修改完成后重新运行即可,选择任意菜单条目都会正确传入对应商品实例调用buy函数。
内容的提问来源于stack exchange,提问作者mkj05
相关产品推荐
相关产品推荐

