python中 lambda的动态构造函数用法!涨知识了!

本文探讨了lambda函数在动态参数传递中的问题,重点介绍了解冻法和双重lambda的解决方案,并揭示了lambda函数执行原理。通过实例演示,解决了tkinter中参数持久化的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们在使用lambda函数的时候常常会遇到这样的问题
lambda函数虽然写好了,但是不够灵活,
比如说,我们在lambda函数中使用一个参数i
在定义参数i的时候它还是指向正确的值,
隔一段时间,它被程序修改了,那么就可能会指向错误的值
导致lambda函数执行时发生不可预测的异常,甚至有时候还没有error

tk.Button(window, text=i + '日志记录', command=lambda:CreateView(i,"Log",Rewrite_data.read_txt(i))).pack()

以tkinter中按钮点击事件传递参数为例
上面这种写法,是打算用循环遍历创建按钮,对于每个按钮传递一个i值作为command回调的参数
但是事与愿违,刚创建的i值很快就会被遍历的下一个循环所覆盖,等到执行按钮回调函数的时候早已不是当初的i值,甚至会因为执行了其他函数,连i值的类型都发生变化。幸好我发现类型变化了,才能快速找到是lambda函数的问题
那么直接给出解决方法吧
第一种是冻结法

tk.Button(window, text=i + '日志记录', command=(lambda i : lambda:CreateView(i,"Log",Rewrite_data.read_txt(i)))(i)).pack()

在lambda函数外再次嵌套一个lambda函数,把i值传递到外层lambda执行一次

a = (lambda i: lambda : print(i))(1)
b = lambda i=1:print(i)
a()
b()

用最简单的方法就可以验证lambda函数的冻结原理
无论是外层lambda还是 lambda 参数赋值,原理都是先执行一次i值的初始化
初始化部分,也就是冒号前面的内容,执行是动态的,相当于冒号后面的函数的构造

c = lambda i: lambda : print(i)
>>> c(1)
<function <lambda>.<locals>.<lambda> at 0x0000022DC471FD38>
>>> c(2)
<function <lambda>.<locals>.<lambda> at 0x0000022DC472D318>

如果改用双重lambda的方式来写,那么每次调用c都会构造一个新的lambda函数
可以动态地构造函数

f = 1
d = lambda i=f:print(i)
>>> d()
1
>>> f = 2
>>> d()
1

如果采用lambda参数赋值的方式来写,那么每次调用lambda都是一样的参数值,在第一次lambda定义的时候就已经成为了静态函数。

最后感谢codeday大佬的技术分享,为我带来了思路 http://www.cocoachina.com/cms/wap.php?action=article&id=66693

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值