1、闭包:
如果一个函数,内部又嵌套了一个函数,且这个内部函数用到了外部函数的局部变量,外部函数将内部函数作为返回值赋给任意一个变量a(相当于内部函数的地址传递给a),那么在调用函数a(),则可以访问到外部函数的局部变量,局部变量可以在函数外部被访问而不会被垃圾回收,直到这个局部变量没有对象使用为止,这种现象称为闭包。其实闭包的一个作用就是保存局部变量,在函数运行结束时不会马上被垃圾回收。举个简单的例子:
闭包的优缺点:
1.闭包似优化了变量,原来需要类对象完成的工作,闭包也可以完成
2.由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存
2、装饰器:
装饰器,装饰器是闭包现象的一种体现,功能就是在运行原来功能基础上,加上一些其它功能,比如权限的验证,比如日志的记录等等。不修改原来的代码,进行功能的扩展。比如java中的动态代理,python的注解装饰器,其实python的装饰器,是修改了代码。
先来举一个简单的例子,假如公司以前基础平台的开发人员在写代码时候没有关注验证相关的问题,即:基础平台的提供的功能可以被任何人使用。现在需要对基础平台的所有功能进行重构,为平台提供的所有功能添加验证机制,即:执行功能前,先进行验证。如果让调用功能的人员自行添加验证的部分,那么每个调用功能的人员都需要自己添加,且不统一,并且非常费事费力。那么这是装饰器就起到了一个很好的作用,基础平台开发人员只需要另外写一个具有验证信息功能的装饰器,几乎不需要改动之前的代码,就可以使每个调用功能的人员在调用该功能之前都有验证的部分,十分方便。
装饰器的工作流程:
1、简单的装饰器:
2、多个装饰器:
多个装饰器,按照从里往外(从下往上)的先后顺序执行,可以理解为先写后运行,先写后结束。
3、带参数的装饰器:
再来一个例子:
4、装饰器示例:
例1:
例2:
例3:
例4:
例5:
例6:被装饰的函数有返回值
没有接收foo函数的返回值,所有其return没有作用,为了通用起见,在inner函数内部接收func函数的返回值。
下面的例子帮助更好的理解装饰器的执行过程:
通用装饰器:
5、类装饰器:
在python中,变量名()这种方式通常表示的是调用变量名的这种类或方法,想类,函数都是可以调用的,但实例对象虽然具有类的方法和属性,但是却是不可调用的,如下图中,Dog类可以调用,erha这个实例对象不可调用。
造成上述的现象是因为class也属于对象,它是内置的type类的对象,type类中具有__call__这一魔法方法,因此Dog类可以被调用,erha是Dog类的实例对象,而Dog类中没有__call__的魔法方法,因此erha这一实例对象不可被调用,若要erha这一实例对象,需在Dog类中加入__call__的魔法方法
运行如下代码:
从结果可以看出,此时laowang的id和实例对象self的id是一样的,就说明了laowang就是这一实例对象,func指向了laowang原本的函数体
从结果可以看出,类装饰器不仅可以使实例对象可调用,并且实现了在类的外部访问类的私有属性的功能。
例: