摘自廖雪峰老师的博客
核心
返回闭包时,返回函数中不要引用任何后续可能变化的变量;
(如果一定要引用,就在原返回函数中再定义一个函数,用该函数中的参数绑定可能变化的变量的当前值。)
对比例子
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
print f1() # f1运行结果为9
print f2() # f2运行结果为9
print f3() # f3运行结果为9
三个函数运行结果都为9的原因:fs中保存着三个返回的函数f,三个函数中都引用了i,当函数运行时候,i已经变为3了。所以说:“返回函数中不要引用任何后续可能发生变化的变量”。
def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
return fs
f1, f2, f3 = count()
print f1() # f1运行结果为1
print f2() # f1运行结果为4
print f3() # f1运行结果为9
三个函数运行结果分别为1、4、9的原因:fs中保存着三个返回的函数g,g中的参数绑定了循环变量当前值,所以不管f1、f2、f3什么时候运行,结果都为1、4、9。