python Closure(闭包)
闭包(closure)
前戏-普通函数:
函数是一个对象,所以可以作为某个函数的返回结果(类似于decorator)
def num_calculator():
def calculator(x):
return 2*x + 1
return calculator # return function object
num = num_calculator()
print(num(5))
>>>
11
print(num_calculator()(5))
>>>
11
上面的代码可以成功运行。num_calculator将calculator对象返回赋给num。
闭包-引用外围作用域变量:
def num_calculator():
a = 10
def calculator(x):
return 2*x + a
return calculator
num = num_calculator()
print(num(5))
>>>
20
我们可以看到,calculator中引用了外围作用域变量a,但a信息存在于calculator的定义之外。我们称a为calculator的环境变量;一个函数和它的环境变量合在一起,就构成了一个闭包(closure)。
事实上,calculator作为num_calculator的返回值时,calculator中已经包括a的取值(尽管a并不隶属于line)。
在Python中,所谓的闭包是一个包含有环境变量的函数对象。环境变量被保存在函数对象的__closure__属性中。比如下面的代码:
def num_calculator():
a = 10
def calculator(x):
return 2*x + a
return calculator
num = num_calculator()
print(num.__closure__[0].cell_contents)
>>>
10
闭包示例:
def num_calculator(a, b):
def calculator(x):
return a*x + b
return calculator
num1 = num_calculator(2, 3)
print(num1(5))
>>>
13
这个例子中,函数calculator与环境变量a,b构成闭包。在创建闭包的时候,我们通过num_calculator的参数a,b说明了这两个环境变量的取值。
闭包-修改外围作用域变量:
def num_found(lists):
status = False
def found(x):
if x in lists:
nonlocal status
status = True
return status
return found
num = num_found([1,2,3,4,5])
print(num(5))
>>>
True
闭包与并行运算
闭包有效的减少了函数所需定义的参数数目。这对于并行运算来说有重要的意义。在并行运算的环境下,我们可以让每台电脑负责一个函数,然后将一台电脑的输出和下一台电脑的输入串联起来。最终,我们像流水线一样工作,从串联的电脑集群一端输入数据,从另一端输出数据。这样的情境最适合只有一个参数输入的函数。闭包就可以实现这一目的。
并行运算正称为一个热点。这也是函数式编程又热起来的一个重要原因。函数式编程早在1950年代就已经存在,但应用并不广泛。然而,我们上面描述的流水线式的工作并行集群过程,正适合函数式编程。由于函数式编程这一天然优势,越来越多的语言也开始加入对函数式编程范式的支持。

浙公网安备 33010602011771号