前言
装饰器是一种著名的设计模式,允许我们动态的为一个对象来添加一些额外的功能而无需去修改它所在的类或者是创建新类。python中的函数也是一种对象,下面用几个函数实例来说明python中的装饰器。
需求
首先从最简单的开始,假设我们有如下的函数:
def my_func():
print 'do something'
现在的需求是需要在每次执行该条语句之前输出日志start dosomething
,方便以后分析,最直观的方法就是就是修改函数体在其中增加日志输出语句或者在程序中每处调用的my_func
的地方增加输出语句,这两个方法明显都是不可取的,在这样的场合我们需要装饰器。
简单实现
实现上面需求的最简单的python装饰器如下:
def decorator(func):
def log():
print 'start to do something'
func();
return log
@decorator
def my_func():
print 'do something'
现在我们执行 my_func()
,程序输出如下:
start to do something
do something
可以看见,原来的my_func
函数拥有了新的功能,这就是装饰器的作用,动态的给现有的对象增加额外的功能。代码中的decorator
函数就是装饰函数,它接收一个对象,修饰这个对象,并返回一个增强了的新对象,注意python中一切皆对象,函数也是对象。而@decorator
这一句则是python中的一个语法糖,它告诉我们这里使用了装饰器,用decorator
函数来装饰my_func
,在上面代码中函数定义前加上@decorator
这一句其实等效于在函数定以后加上 my_func = decorator(my_func)
,只是@
的符号使我们能够更直观的一眼看出这里使用了装饰器。这里我们实现了一个最简单的装饰器,通过这个简单的例子我们对装饰器有了一个大概的概念,举个通俗的例子,就好比手机贴膜,我们希望自己的手机屏幕能够防指纹,这对应于我们的需求,需要给手机增加新的功能,没有人会去手机店把自己的手机原有的屏幕拆下来,换上新的防指纹的屏幕,更好的办法是去贴膜的地方贴一张防指纹膜,对应于程序也是,有时候我们需要动态的给一个对象增加新功能,修改生成对象的类往往是不可取的,这时候就需要使用装饰器模式,上面程序中的的my_func
函数就相当于我们的手机,decorator
函数就相当于贴膜店,my_func
经过decorator
的处理后增加了日志输出功能就相当于给手机贴了层膜,在不改动my_func
函数实现的情况下我们给其增加了新功能,这点是非常重要的,也是装饰器最大的用处,尤其是在其他语言中,my_func
函数或者要修改对象的具体实现我们并不一定能够知道,想要修改也无从下手的情况下。
有了简单概念后,下一节将会继续介绍带参数的装饰器等稍微复杂的情况