最近在看Fluent python, 也抓了Python中几个重要的点来理解. 希望读者有一定的Python基础.

一段简短的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
In [1]: def make_averager():
...: series = []
...: def averager(new_value):
...: series.append(new_value)
...: total= sum(series)
...: return total /len(series)
...: return averager
...:

In [2]: avg = make_averager()

In [3]: avg(1)
Out[3]: 1.0

In [4]: avg(10)
Out[4]: 5.5

In [5]: avg(7)
Out[5]: 6.0

上面代码中的make_averager的返回值是在其中定义的一个函数averager. 那么, 这个返回值就应该是可以被调用的, 所以就有了avg(1), avg(10). 这看来是顺其自然的事情.

返回函数就是闭包吗?

C/C++也有函数指针这一说, 也可以将其返回, 可我们并不称之为闭包

所以闭包到底是什么呢?

请注意代码中的series数组, 这个数组是在make_averager中定义, 在 In [2]: avg = make_averager()调用过之后, 其他函数是不可以看到以及使用这个变量了 (如果你不懂我说的, 请百度:变量的作用域!).

但是我们在调用In [3]: avg(1)时, 一定是执行了下面嵌在make_averager中的函数

1
2
3
4
def averager(new_value):
series.append(new_value)
total= sum(series)
return total /len(series)

它使用了series数组, 没错, 他就是使用了. 它使用了别的函数无法使用的变量. series数组的作用域扩展到了averager函数, 或者说, averager函数记录了这个变量的 地址, 从而操纵了这个变量. 现在, 变量的作用域被内层函数averager包起来了, 这样才能被称之为闭包.

Fluent Python中的解释

英文截取自: fluent-python-2015.pdf P195

To summarize: a closure is function that retains the bindings of the free variables that exist when the function is defined, so that they can be used later when the function is invoked and the defining scope is no longer available.

Note that the only situation in which a function may need to deal with external variables

闭包就是函数可以保留对free varilables的绑定, 这些变量其实只在函数定义时存在. 但是拥有了绑定之后, 他们还是可以在函数被调用时进行读写, 尽管定义域已经不在了

  • 希望我将闭包的概念解释清楚了, 也欢迎提出疑问.