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年代就已经存在,但应用并不广泛。然而,我们上面描述的流水线式的工作并行集群过程,正适合函数式编程。由于函数式编程这一天然优势,越来越多的语言也开始加入对函数式编程范式的支持。

  

posted @ 2016-12-14 22:30  Vincen_shen  阅读(330)  评论(0)    收藏  举报