python装饰器
python装饰器是python学习过程中难度不高,但是功能强大的一个知识点,在面试python过程中,经常被问到相关的知识(另外两个python迭代器,生成器也经常被面试官问到),下面简单介绍下python装饰器的功能,实用场景
1、在解释python装饰器之前,先简单介绍写闭包
闭包是由函数和及其相关引用环境组合而成的实体,通俗的讲就是,如果在一个内部函数里,存在对在外部作用域(但不是在全局作用域)的变量的引用,那么内部函数就被认为是闭包(closure)。它只不过是个“内层”的函数,由一个名字来指定。,以下例子就是一个简单的闭包,
2、装饰器
装饰器是一个很著名的设计模式,本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象,经常被用于有切面需求的场景,较为经典的有插入日志、性能 测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器 的作用就是为已经存在的对象添加额外的功能。
(1)先来看一个简单例子,该函数简单打印出name
(2)现在有一个新的需求,需要在打印出name之前提示打印日志,最简单的方法就是在函数内部实现:
(3)如果get_age(age)、get_sex(sex)都需要在打印之前打印出日志,那么在方法体内需要写大量的logging.warning(xxxxx),为了减少重复写代码,我们可以这样做,重新定义个 函数:专门处理日志 ,日志处理完之后再执行真正的业务代码
逻辑上不难理解, 但是这样的话,我们每次都要将一个函数作为参数传递给use_logging函数。而且这种方式已经破坏了原有的代码逻辑结构,之前执行业务逻辑时,执行运行bar(),但是现在不得不改成use_logging(bar)。那么有没有更好的方式的呢?当然有,答案就是装饰器。
3、简单装饰器
从下面的例子来看,装饰其其实就是一个简单的闭包
函数info_logging就是装饰器,它把执行真正业务的方法func包装在函数里面,看其来get_name被info_logging装饰了,@符号是装饰器的语法糖,在定义函数的时候使用,避免再一次赋值操作
4、带参数的装饰器
上面的info_log是允许带参数的装饰器。它实际上是对原有装饰器的一个函数封装,并返回一个装饰器。我们可以将它理解为一个含有参数的闭包。当我 们使用@info_log(level="warning")调用的时候,Python能够发现这一层的封装,并把参数传递到装饰器的环境中。