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