Python小知识——注意

如果lambda或者def在函数中定义,嵌套在一个循环之中,并且嵌套的函数引用了一个上层作用域的变量,该变量被循环所改变,所有在这个循环中产生的函数将会有相同的值——在最后一次循环中完成时被引用变量的值。

例如,下面的程序试图创建一个函数的列表,其中每个函数都记住嵌套作用域中当前变量i的值 。

>>>def makeActions():
...    acts = []
...    for i in range(5):
...        acts.append(lanbda x:i ** x)
...    return acts
...
>>>acts = makeActions()
>>>acts[0]
<function <lambda> at 0x012B16B0>
尽管这样,但这并不怎么有效:因为嵌套作用域中的变量在嵌套函数被调用时才进行查找,所以它们实际上记住的是同样的值。也就是说,我们将从裂变中的每个函数得到4的平方的函数,因为i对于在每一个列表中的函数都是相同的值4。

>>>acts[0](2)
16
>>>acts[2](2)
16
>>>acts[4](2)
16
这是在嵌套作用域的值和默认参数方面遗留的一种仍需要解释清楚的情况,而不是引用所在的嵌套作用域的值。也就是说,为了让这类代码能够工作,必须使用默认参数把当前的值传递给嵌套作用域的变量。因为默认参数是在嵌套函数创建时评估的(而不是在其稍后调用时),每一个函数记住了总觉得变量i的值。

>>>def makeActions():
...    acts = []
...    for i in range(5):
...        acts.append(lambda x,i=i: i ** x)
...    return acts
...
>>>acts = makeActions()
>>>acts[0](2)
0
>>>acts[2](2)
4
>>>acts[4](2)
16
这是一种相当隐晦的情况,但是它会在实际情况中发生,特别是在生成应用于GUI一些部件的回调处理函数的代码中(例如,按钮的事件处理)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值