本文只讲一个重点:闭包与for循环之间的矛盾以及避免的方法,关于闭包的概念,请参考网上的概念
废话不多说来看以下代码:
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
如上所示,很经典的闭包使用,那么如果我们执行f1()并且打印它的返回值答案会是多少,我想很多人会认为是1,但结果不尽人意,我们打印出f1,f2,f3的值我们发现答案竟然是一样的都是9,原因在于闭包中,那个被返回的函数并没有立即执行,而是以某种方式保存了下来,其实,在生活中,就好比你有一个苹果,当你咬下一口让它暴露在空气中以后,再次使用(吃)会被氧化发生了改变一样,闭包的关键在于函数内部能够调用外部的数据,但这些数据的值一定要以最终的形态被内部函数调用,上述代码中,当执行f()时(吃到苹果)那个外部的变量才不会再发生改变,但是在count内部调用不到f()函数所以只能以最后for循环结束的那个3作为i传入
如果一个苹果在外面暴露的太厉害有什么解决方法可以防止苹果氧化吗?
解决方法就是我们把苹果包在一个袋子里这样,就可以减慢氧化的速度,其实解决这个问题也是这样,在f函数外面加一层保护膜:
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
在外面的函数中加一个参数绑定当前的i值,我们这样就可以有效的防止闭包的弊端,能够实时的将i的值传给内部函数