(五)函数装饰器和闭包
一、装饰器的基础知识
1、装饰器是可调用对象,其参数是另一个函数(被装饰的函数)。装饰器会处理被装饰的函数,然后将其返回,或者将其替换成另一个函数或可调用对象。
替换成另一个函数
2、装饰器的两大特性,一是能把被装饰的函数替换成其他函数,二是装饰器在加载模块是立即执行。
二、python何时执行装饰器
1、装饰器,在被装饰的函数定义之后,立即执行(通常在导入模块时执行)。如下例子,最先执行running register(f1,f2),然后是running main()
2、应用时,通常装饰器在一个模块内,被装饰的函数在另一个模块内
3、上例中,参数传入的函数与被返回的函数相同,通常并不这么做:在装饰器内部定义一个函数,然后将其返回。
三、装饰器应用于策略模式
选择最佳的促销模式
五、闭包
通常,装饰器内部会定义一个函数,然后将其返回,替换被装饰的函数。内部函数的完成,依靠的就是闭包。
1、变量作用域规则
内部函数的赋值操作,会使变量变为局部变量。如果想当成全局变量,则在f2中声明global b
2、闭包
闭包指延伸了作用域的函数,包含函数体中定义的引用、不在定义体中定义的非全局变量,函数可以访问定义体之外定义的非全局变量(有点类似于static变量)。
闭包会保留定义函数时存在的自由变量的绑定。
3、nonlocal声明
当count是数字或任何不可变类型(字符串、元组)时,赋值语句会把count变为局部变量。
python3中引入nonlocal声明,把变量标记为自由变量,即使在函数中重新赋值,也会变成自由变量。
python2中通过将变量设置为可变变量(列表、字典)来解决
六、实现一个简单的装饰器
这下知道了装饰的含义。
装饰器的典型行为:把被装饰的函数替换为新的函数,二者接受相同的参数,而且返回被装饰函数本该返回的值,同时还会做些额外操作。
七、标准库中的装饰器
python内置三个用于装饰方法的函数:property,classmethod和staticmethod。
1、使用functools.lru_cache做备忘:它把耗时的函数结果保存起来,避免传入相同参数时的重复计算。
如下生成斐波拉且数列
2、functools.singledispatch
没看太明白
八、叠放装饰器
九、参数化装饰器
Python把被装饰的函数作为第一个参数传给装饰器函数,如果想让装饰器接受其他参数,则创建一个装饰器工厂函数,把参数传给它,返回一个装饰器,再将其应用到要装饰的函数上。