装饰器
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
举例解释:
def func1():
some options
我们现在拥有一个已经运行了一段时间的功能函数 func1,一天我们需要一些新的功能,由于不能直接修改线上函数func1,怎么办?这时我们就可以利用装饰器。
定义一个新的装饰器函数 decorater
def auth(func): def inner(): print "so some things here" func() return inner @auth def func1(): print "this is func1 result" func1()
执行结果
so some things here
this is func1 resule
解释:装饰器函数接收被装饰的函数名称,执行内部inner函数并返回inner对应内存地址。inner函数内部函数块就可以写上新的功能。我们在进行新功能函数调用时,即可执行新功能,还不用修改原函数,用户进行调用时也不需要进行代码修改。
缺陷:无法传递参数。
装饰带参数的函数
在我们定义函数时,经常需要进行参数的传递,装饰器怎么进行装饰带参数的函数呢?将装饰器添加上函数即可!即带参数的装饰器。
def auth(func): def inner(argv): 这里用于接收参数,以便将参数传递给后边的被装饰func函数 print "so some things here" func(argv) return inner @auth def func1(): print "func1 result" print argv func1('argv1')
执行结果:
so some things here
func1 result
argv1
同理我们如果需要传递多个参数或者动态参数时,我们在装饰器内存函数inner修改为接收多个参数或者动态参数即可。并且装饰器会自动将动态参数进行自动匹配给对应的函数。即如果有的函数不需要参数有的需要参数,我们只使用一个装饰器即可。
def decorater(func): def inner(*args,**kwargs): //do some options here func(*args,**kwargs)
现在又遇到一个问题,我们的函数这里没有return值,能装饰带return的函数吗?
装饰器装饰带return函数的参数
在代码:
def auth(func): def inner(): print "so some things here" func() return inner @auth def func1(): print "this is func1 result" return result func1()
这里的函数func1带有return函数,但在实际的操作中我们使用了装饰器以后却获取不到返回值,为什么?因为我们使用了装饰器以后我们的原函数成为了装饰器inner函数的一部分,inner函数的接收到func1的return返回值,但是inner并没有return返回,所以我们获取到的return是none。
因此只要将inner函数获取到的func1函数的return值再继续return即可获得。
多层装饰器执行顺序
当装饰器 有多层时,即多个装饰器对同一个函数进行装饰时,顺序从上到下进行执行。
装饰器函数参数
@wapper(func1,func2)
执行顺序:1. 执行wapper(func1,func2) 2. 上一步的执行结果如果等于一个目标结果如ret 3.执行@ret 装饰器
即整个过程动态生成了一个装饰器。