python闭包与装饰器
闭包
什么是闭包?简单来讲:
内部函数作为返回值给出,外部变量接收绑定后可以使用,闭包可以保存函数内部特定运行的一个状态
形成闭包很容易:
- 外部函数中定义了内部函数
- 外部函数是有返回值的
- 返回的值是内部函数名(其实是其绑定的对象)
- 内部函数引用了外部函数的变量
1 | |

生成闭包后,内部函数的调用就不依赖外部函数了,它自身已经保存了外部函数的状态,可以在如上程序第三行加上print(“here!”)验证
闭包的总结:
- 闭包优化了变量,原来需要类对象完成的工作,闭包也可以完成
- 由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存
- 闭包的好处:使代码变得简洁,便于阅读代码
- 闭包是理解装饰器的基础
装饰器
描述过程可能比较不具体,所以直接上个实例,顾名思义,装饰器是用来装饰一个函数的,它可以大大提升程序的可扩充性
实例
抛出问题
我有一个函数,原来写的,我叫它毛坯房,其实它也只打印出了这个,它一定需要修饰
1 | |
这个函数在我的项目中总共调用了100次,使用量还是挺大的,我想给他增加一些特定的功能,当然这不是什么问题,加就是了,关键我加了100行
1 | |
这也不是什么问题,100多次的fun()的调用依然没有什么问题,但是问题来了,我要恢复原来fun()的基本功能,然后新加入新的功能,有点难了,这么多代码纵横交错在一起
当然这也不是什么困难的东西,使用版本管理工具回退历史查看,复制拷贝然后就ok了
但不幸的是,你被告知,对这个函数这样的更改还有很多次,被改的函数还有很多个,你有点儿慌了,这是什么事儿啊!
我花费很多功夫,做的事情好多好像失去了编程的意义。你陷入了沉思
解决问题
有没有一种写法,不用更改我原来的fun(),保持它的基本功能,使用另一个函数来修饰它;不同的修饰可以写成不同的函数,使用过后还可以复用。然后使用一个函数来装饰就像给函数戴个帽子一样,方便脱戴。
python的装饰器来了
解决方法:
1 | |

1 | |

使用了不同的装饰器,给function()增加了不同的额外功能
详解
如图显示了函数名作为参数传递的过程,解释了它为什么能够装饰一个函数

- function()是被装饰函数
- 将被装饰函数作为参数传给装饰器decorate
- 执行decorate函数
- 将返回值又赋值给function
而装饰一个函数只需要给一个函数头上加上@装饰器名
它明显可以解决上面我抛出的问题
多层装饰器
多层装饰器,谁距离近,就优先调用谁
1 | |

从这里我们可以看到多层装饰器的执行过程
带参数的装饰器
需要多写一层:
1 | |
