一、定义
闭包(Closure):内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数。
二、举例
1、求一列表(list)中所有元素的和
def calc_sum(lst):
def lazy_sum():
return sum(lst)
return lazy_sum
f = calc_sum([1, 2, 3, 4]) # 调用calc_sum()并没有计算出结果,而是返回函数f print f() # 对返回的函数进行调用时,才计算出结果
注:上例说明了返回函数可以把一些计算延迟执行。
2、求一列表(list)中所有元素的积
def calc_prod(lst): def lazy_prod(): def f(x, y): return x * y return reduce(f, lst, 1) return lazy_prod
f = calc_prod([1, 2, 3, 4]) print f()
三、易错点
闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。举例如下:
# 希望一次返回3个函数,分别计算1x1,2x2,3x3:
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
当count()函数返回了3个函数时,这3个函数所引用的变量 i 的值已经变成了3。由于f1、f2、f3并没有被调用,所以,此时他们并未计算 i*i,当 f1 被调用时:
>>> f1() 9 # 因为f1现在才计算i*i,但现在i的值已经变为3
因此,返回函数不要引用任何循环变量,或者后续会发生变化的变量。
下面改写count()函数,使其能够正确返回能计算1x1,2x2,3x3的函数。

它可以正确地返回一个闭包g,g所引用的变量x不是循环变量,因此将正常执行。还需要注意,在count函数的循环内部,如果借助g函数,就可以避免引用循环变量i。
注:以上内容整理自【慕课网】
浙公网安备 33010602011771号