闭包(Closure)是词法闭包(Lexical Closure)的简称。对闭包的具体定义有很多种说法,这些说法大体可以分为两类:
一种说法认为闭包是符合一定条件的函数,另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
这两种定义在某种意义上是对立的,一个认为闭包是函数,另一个认为闭包是函数和引用环境组成的整体。虽然有些咬文嚼字,但可以肯定第二种说法更确切。闭包只是在形式和表现上像函数,但实际上不是函数。函数是一些可执行的代码,这些代码在函数被定义后就确定了,不会在执行时发生变化,所以一个函数只有一个实例。
闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。那么为什么要把引用环境与函数组合起来呢?这主要是因为在支持嵌套作用域的语言中,有时不能简单直接地确定函数的引用环境。
闭包和函数对象本质上是同一种东西,闭包是函数对象的简化。闭包将环境数据保存在func_closure中,函数对象则将相关数据保存在对象中。二者均可用于filter、map、reduce等函数中。
下面分别使用闭包和函数对象来做同一件事情,感觉二者非常相似
<
?[Copy toclipboard]View Code PYTHONIn [68]: class counter_class():
def __init__(self, start_at):
self.start_at = start_at
def __call__(self):
self.start_at += 1
return self.start_at
....:
....:
In [74]:
In [75]: c1 =counter_class(5)
In [76]: c1()
Out[76]: 6
In [77]: c1()
Out[77]: 7
In [78]: c1()
Out[78]: 8
>
<
In [80]: def counter_closure(start_at= 0):
count = [start_at]
def incr():
count[0] += 1
return count[0]
return incr
....:
In [86]: c2 =counter_closure(5)
In [87]: c2()
Out[87]: 6
In [88]: c2()
Out[88]: 7
In [89]: c2()
Out[89]: 8
>
Python因其简单易学、功能强大而拥有很多拥护者,很多企业和组织在使用这种语言。Python使用缩进来区分作用域的做法也十分有特点。下面是一个Python的例子:
<
清单 6. Python 1
def addx(x):
def adder (y):return x + y
return adder
add8 = addx(8)
add9 = addx(9)
print add8(100)
print add9(100)
>
在Python中使用def来定义函数时,是必须有名字的,要想使用匿名函数,则需要使用lambda语句,象下面的代码这样:
<
清单 7. Python 2
def addx(x):
return lambda y:x + y
add8 = addx(8)
add9 = addx(9)
print add8(100)
print add9(100)
>