今天我们来看一下函数的闭包(closure)。python中学到高级语法,闭包是逃不开的话题,无论是高阶函数还是装饰器等,不理解闭包会寸步难行。
来看代码
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
调用函数返回的是一个list,里面包含三个因for循环返回的func。要注意的是,当运行到 fs.append时,这里是f函数对象本身被当做参数传了进去,所以并不会直接执行。当最下面调用f1()f2()f3()时,list中的3个返回的函数才会真正执行,然而会发现执行的结果是 9,9,9。因为此时的i是3。
如果我们想用循环变量怎么办呢?看下面的代码
def foo():
fs=[]
for i in range(1,4):
def f(i):
def g():
return i*i
return g
fs.append(f(i))
return fs
print foo()
print foo()[0]()
这个代码体现了闭包的特点,每次循环的时候,把变量 f(i) 当参数传进了list中,也就保留了当时的函数的变量。在之后引用函数的时候,才不会出现第一种代码的情况。闭包重要的一点,就是返回的函数对象当时并不会执行,而是等下次调用的时候才会一层一层的执行。而返回的是一个函数调用,则会执行,再保存返回结果,在此例中,fs.append(f(i))此处,f(i)执行并返回一个g 函数对象本身。等到函数最后 print 时 才再一个调用函数。