当想为写好的函数添加新功能而又不想或不方便更改原函数时,就可以使用装饰器来解决,如添加计时器,日志记录,权限认证等,有人将此概括为有切面需求的场景。简单来说,就是为已有的对象添加附加功能,就好像在进行“装饰”。
最简单的装饰器
在python中,函数或者说函数名可以作为另一个函数的参数,而装饰器就是以被装饰函数作为参数,对其进行加工修改,并返回修改后的函数名。
|
为了体现出执行过程,加入打印信息。
|
在wrapper()函数内,就可以在func()前后添加附加功能,对其进行“装饰”。
加入语法糖@
为了进一步简化代码,python加入了@。下面的@deco等价于foo = deco(foo)。其实也没做多少简化,但使用@能明显感觉到加强了代码的可读性。
|
被包装函数是有参、有返回值函数
|
*args, **kwargs
(*args, **kwargs)可接受各种类型的参数
|
装饰器带普通参数
与前例相比,需要在外面再加一层包装。
|
装饰器带类参数
与四的使用方式类似。但要注意的是想要在装饰器中使用的类方法需要声明为静态方法( @staticmethod),因为该类并没有进行实例化。
|
多个装饰器
|
@functools.wraps()
函数有几个特殊属性比如函数名,在被装饰后,函数名会变成装饰器的包装函数的名字(如下例中的wrapper)。如果你希望使用反射,或者用到了如函数名这样的特殊属性,之前几个例子的装饰器使用方式就会导致意外的结果。functools就可以解决这个问题,将@functools.wraps(func)置于最内层包装函数之前,它能将装饰过的函数的特殊属性保留。
|
|
参考资料
http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html
http://www.cnblogs.com/evilliu/p/5546877.html
http://blog.csdn.net/thy38/article/details/4471421