最近我开始玩Python,我遇到了一些特殊的闭包方式.请考虑以下代码:
adders=[0,1,2,3]
for i in [0,1,2,3]:
adders[i]=lambda a: i+a
print adders[1](3)
Run Code Online (Sandbox Code Playgroud)
它构建了一个简单的函数数组,它接受单个输入并返回由数字添加的输入.函数在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值?def makeActions():
acts=[]
for i in range(5):
print len(acts)
acts.append(lambda x: i ** x)
print acts[i]
return acts
acts=makeActions()
for i in range(5):
print acts[i](2)
Run Code Online (Sandbox Code Playgroud)
输出:
16
16
16
16
16
Run Code Online (Sandbox Code Playgroud)
预期产量:
0
1
4
9
16
Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
def f (a):
return 1
def g (a):
return 2
[lambda a: i(a) for i in (f,g)][0](0)
Run Code Online (Sandbox Code Playgroud)
结果是 2。它显然应该是 1!我希望这段代码执行如下。创建一个列表。将函数 f 复制到第一个索引中。将 g 复制到第二个索引中。鳍。
为什么会这样执行?!