闭包就是在函数内再定义一个函数,并作为结果返回。
需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了 f()
才执行。我们来看一个例子:
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
a, b, c = count()
你可能认为调用a()
,b()
和c()
结果应该是1
,4
,9
,但实际结果是:
>>> a()
9
>>> b()
9
>>> c()
9
全部都是9
!原因就在于返回的函数引用了变量i
,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i
已经变成了3
,因此最终结果为9
。
具体细节参看: 代码可视化
练习
利用闭包返回一个计数器函数,每次调用它返回递增整数:
def createCounter():
j=0
def counter():
nonlocal j
j=j+1
return j
return counter
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA())
# 1 2 3 4 5
为什么要用 nonlocal
呢?因为 j 是不可变类型,虽然在 counter()
中能传进来,但无法修改,所以要定义成 nonlocal 类型。