最近,我开始玩弄Python,并且在闭包的工作方式中遇到了一些奇怪的事情。考虑以下代码:
adders=[0,1,2,3]
for i in [0,1,2,3]:
adders[i]=lambda a: i+a
print adders[1](3)
它构建了一个简单的函数数组,这些函数接受单个输入并返回该输入加数字后的结果。这些函数在for
循环中构造,其中迭代器i
从0
到运行3
。对于这些数字中的每一个,lambda
都会创建一个函数,将其捕获i
并将其添加到函数的输入中。最后一行使用参数作为参数调用第二个lambda
函数3
。令我惊讶的产量6
。
我期望一个4
。我的推论是:在Python中,一切都是对象,因此每个变量都是指向它的指针。为创建lambda
闭包时i
,我希望它存储一个指向当前由指向的整数对象的指针i
。这意味着,当i
分配一个新的整数对象时,它不应影响先前创建的闭包。可悲的是,adders
在调试器中检查该阵列是否可以完成。所有的lambda
功能指的最后一个值i
,3
,其结果adders[1](3)
返回6
。
这让我想知道以下几点:
- 闭包到底捕获了什么?
- 用最优雅的方法说服
lambda
功能捕获当前值,i
而该方法在i
更改其值时不会受到影响?
i
离开命名空间?
print i
循环后将不起作用。但是我自己进行了测试,现在我明白了您的意思-它确实有效。我不知道循环变量在python的循环体之后仍然存在。
if
,with
,try
等等