【第十七天】闭包的用法

作者: 人生苦短_我用Python | 来源:发表于2018-03-29 22:06 被阅读16次

3.闭包

上面函数中,line()定义嵌套在另一个函数内部
如果函数的定义中引用了外部变量,会发生什么呢?

def line_conf():
    b = 15
    def line(x):
        return 2*x + b
    b = 5
    return line       #返回函数对象

if __name__ == '__main__':
    my_line = line_conf()
    print(my_line(5))  #打印15

可以看到,line()定义的隶属程序块中引用了高层级的变量b
b的定义并不在line()的内部,而是一个外部对象
我们称b为line()的环境变量,尽管b位于line()定义的外部
但当line被函数line_conf()返回时,还是会带有b的信息

一个函数的它的环境变量合在一起,就构成了一个闭包(Closure)
上面程序中,b分别在line()定义的前后有两次不同的赋值
上面的代码将打印15,也就是说,line()参照的是值为5的b值
因此,闭包中包含的是内部函数返回时的外部对象的值

在py中,所谓闭包是一个包含有环境变量取值的函数对象
环境变量取值被复制到函数对象的closure属性中
比如下面代码:

def line_conf():

    b = 15
    def line(x):
        return 2*x + b
    b = 5
return line        #返回函数对象

if __name__ == '__main__':
    my_line = line_conf()
    print(my_line.__closure__)
    print(my_line.__closure__[0].cell_contents)
(<cell at 0x1074379a8: int object at 0x10268f5d0>,)
5

可以看到,my_line()的closure属性中包含了一个元组
这个元组中的每个元素都是cell类型的对象
第一个cell包含的就是整数5,也就是我们返回闭包时的环境变量b的取值

闭包可以提高代码的可复用性,下面看四个函数:

def line1(x):
    return x + 1
def line2(x):
    return 4*x + 1
def line3(x):
    return 5*x + 10
def line4(x):
    return -2*x - 6

如果把上面的程序改为闭包,那么代码就会简单很多:

def line_conf(a,b):
    def line(x):
        return a*x + b
    return line
    
line1 = line_conf(1,1)
line2 = line_conf(4,5)
line3 = line_conf(5,10)
line4 = line_conf(-2,-6)

这个例子中,函数line()与环境变量a,b构成闭包
在创建闭包的时候,我们通过line_conf()的参数说明直线的参量
这样,我们就能复用同一个闭包,通过代入不同的数据来获得不同的直线函数
如y=x+1和y=4x+5,闭包实际上创建了一群形式相似的函数

除了复用代码,闭包还能起到减少函数参数的作用:

def curve_closure(a,b,c):
    def curve(x):
        return a*x**2 + b*x + c
    return curve
curve1 = curve_closure(1,2,1)

函数curve()是一个二次函数,它除了自变量x外
还有a,b,c三个参数,通过curve_closure()这个闭包
我们可以预设a,b,c三个参数,从而起到减参的效果

闭包的减参作用对于并行运算来说很有意义
在并行运算环境下,我们可以让每台电脑负责一个函数
把上一台电脑的输出和下一台电脑的输入串联起来
最终,我们像流水线一样工作,由于每台电脑只能接受一个输入
所以在串联之前,必须用闭包之类的方法把参数的个数降为1

相关文章

  • 【第十七天】闭包的用法

    3.闭包 上面函数中,line()定义嵌套在另一个函数内部如果函数的定义中引用了外部变量,会发生什么呢? 可以看到...

  • python函数部分

    什么是闭包,闭包的常用用法,怎样判断是不是闭包,闭包的作用是 1、什么是闭包 2、常用用法 3、判断是不是闭包 4...

  • 深入解析Javascript闭包及实现方法

    一、什么是闭包和闭包的几种写法和用法 1、什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的...

  • Swift之闭包

    swift中没有了OC的block,由闭包取而代之。这里简介一下闭包的用法。 声明一个闭包 var clickPa...

  • 理解闭包、立即执行函数、异步和回调

    闭包 什么是闭包 一个函数使用了它外面的变量,这种用法就是闭包。闭包是一个马后炮的总结。 那为何要这样做呢(搞得这...

  • Groovy<第八篇>:基础语法(7)---闭包(Closure

    闭包是Groovy语言最常用的用法之一,Closure是闭包的意思。闭包是一个短的匿名代码块。它通常跨越几行代码。...

  • Swift闭包的用法

    一、typealias(别名)的用法1、重新定义闭包类型swift的闭包书写虽然好看了不少,但是如果大批量的书写闭...

  • Swift学习:闭包

    本篇将详细总结介绍Swift闭包的用法;闭包是自包含的函数代码块,可以在代码中被传递和使用。Swift中的闭包与C...

  • 前端(数组,闭包,定时器)

    数组 定时器 定时器弹框 定时器的基本用法 定时器动画 闭包 闭包存循环的索引值 闭包做私有变量计数器 闭包做选项卡

  • Python 2 - 高级用法 - 装饰器

    Python 2 - 高级用法 - 装饰器 一谈到 装饰器,就离不开闭包 闭包 闭包就是能够读取其他函数内部变量的...

网友评论

    本文标题:【第十七天】闭包的用法

    本文链接:https://www.haomeiwen.com/subject/dxwvcftx.html