---恢复内容开始---
使用像javascript和python这样支持面向对象范式的语言进行编程时,都会涉及到闭包的概念以及闭包的使用。我们今天就从这两个方面来讨论一下闭包:
首先是维基百科中关于闭包的概念:
在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。
根据这句话,其实我们自己就可以总结出在python语言中形成闭包的三个条件,缺一不可:
1)必须有一个内嵌函数(函数里定义的函数)——这对应函数之间的嵌套
2)内嵌函数必须引用一个定义在闭合范围内(外部函数里)的变量——内部函数引用外部变量
3)外部函数必须返回内嵌函数——必须返回那个内部函数
前两个条件我们比较好理解,那什么会有第三条规定呢?其实闭包一词指的就是上文中提到的那个“内部的函数”,我们下面就会发现,只有那个内部函数才有所谓的__closure__属性。
我们根据上面的三准则创造了一个函数,其中的funy就是所谓的闭包,而funy内部所引用过的y就是所谓的闭包变量。
内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,
还给内存,局部变量都会消失。
但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。
2.装饰器
装饰器就是闭包,但装饰器传入的参数是函数
因为python是一门胶水语言,在python一切皆是对象,python中全部都是引用类型
因此函数可以像变量一样被指向和传递。
def diguo(): print("地锅50") return 50def doupi(fn): def jia(): print("豆皮10") return fn()+10 return jiadef xiang(fnn): def jia(): print("香菜") return fnn()+5 return jiaaa=doupi(xiang(diguo))print(aa())这样写起来是不是挺乱的,在python中实现了语法糖
看见@方法名了吗?那就是python自带的语法糖为了简写也可以取到和装饰器调用一样的效果,这样的程序看起来是不是就简洁了很多
在设计模式中装饰器就如同他的名字一样把他装饰起来
装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的应用有插入日志、增加计时逻辑来检测性能、加入事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
原文地址:https://www.cnblogs.com/lihangfei/p/9159788.html