一、
装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
二、装饰器工作原理。
遵循编程的闭合原则,在不修改原函数代码的基础上增加功能,使用装饰器是一种很好的选择。
装饰器工作基于以下两步完成:
第一步:被装饰的函数作为参数传给装饰器函数,并执行装饰器函数,返回值记作newFunction;
第二步:原函数名重新被赋值为newFunction。
def auth(fun): #定义装饰器 def inner(): print("The test code") fun() print("after") return inner @auth #相当于 f1 = auth(f1) 也叫加载装饰器 def f1(): #被装饰的函数 print("----f1执行过程----") f1() #调用函数 #执行结果为 The test code
# ----f1执行过程----
# after
当执行f1函数时,首先执行装饰器auth,并将原f1函数作为参数传递给装饰器函数,装饰器返回一个inner函数并将该函数赋值给f1,即f1() = inner()
auth 这个函数实现的功能是,接收一个函数作为参数然后返回创建的另一个函数f1()=inner(),在这个创建的函数里调用接收的函数(文字比代码绕人)
三、动态参数,装饰含有N个参数的函数。
def auth(fun): #定义装饰器 def inner(*args,**kwargs): #定义动态参数 print("The test code") fun(*args,**kwargs) #将动态参数传给原函数 print("after") return inner @auth #相当于 f1 = auth(f1) 也叫加载装饰器 def f1(): #被装饰的函数 print("----f1执行过程---- ===========") @auth def f2(name,age): print("f2执行过程:name is + %s; age is + %s" %(name,age)) f2("gyc",33)
#执行结果为
#The test code
#f2执行过程:name is + gyc; age is + 33
#after
装饰含有不同参数个数及格式的函数,可以给装饰器定义动态参数,由装饰器将动态参数传递给原函数
四、装饰有返回值的函数。
def outer(func): #定义装饰器 def inner(*args,**kwargs): #为inner函数定义返回值 print("执行原函数之前") r = func(*args,**kwargs) #接受原函数的返回值 print("执行原函数之后") return r #返回原函数的返回值 return inner @outer def f1(): print("f1执行过程") @outer def f2(name,age): print("f2执行过程") rst = 'name is '+name+';age is'+age return rst r1 = f1() print("不接受参数,且无返回值:%s"%r1) r2 = f2('gyc','18') print("接受参数,且有返回值:%s"%r2)
执行结果
五、多层装饰器(同时加载多个装饰器)
六、带参数的装饰器
带参数的装饰器更为灵活,可以接收任意函数作为参数,然后动态生成新的基础装饰器,然后用新装饰器去装饰原函数。
这样,可以指定在原函数执行前运行某一个程序,在原函数执行之后运行另一个程序。