刚开始接触python的时候,感觉装饰器很高大上,也不好理解,时间长了感觉也不过如此,在此将自己的理解整理如下:
装饰器存在的目的是增强python程序的可扩展性及健壮性。其主要作用就是在基本不改变原有代码结构的基础上,添加实现新功能。
一、普通装饰器
举例如下,为方便起见,例程尽量简单:
某系统设计函数计算两个数字之和,并调用了该函数:
def calNumber(a,b):
c=a+b
return c
h=sqrt(calNumber(3,5))
print(h)
后来使用过程中发现a,b的值可能为负数,显然,如果为负数的话将会影响后面程序的调用,因为h要通过开平方后才能得到,所以要进行修正,但是为尽量不影响原程序,采用装饰器来修正:
def newCal(func): #装饰器函数,参数是要修订的函数
def wrapF(a,b) #参数与要修订函数的参数一样,当然也可以用def wrapF(*args,**kwargs)
a=abs(a)
b=abs(b) #对a,b取绝对值,确保a,b不为负数,这是我们所假定的情况,当然要符合实际需要
return func(a,b) #修订完成后再调用calNumber(a,b)函数,注意:调用结果直接到h中去了
return wrapF #实际是在此调用wrapF
#在原程序中只需要加一个修饰符@newCal,当然,上面的装饰器函数要放到程序中合适位置。
@newCal
def calNumber(a,b):
c=a+b
return c
h=sqrt(calNumber(3,5))
print(h)
那么,装饰器功能怎么实现呢?当程序运行到 h=sqrt(calNumber(3,5))时,会调用def calNumber(a,b),调用时发现该函数是一个被装饰的函数,因为其前面有@newCal,于是程序就去调用装饰器函数def newCal(func),在该函数中return语句前没有可执行语句,于是执行return,这时实际就调用其内部定义的函数wrapF(a,b),该函数对参数进行了修订后,再调用calNumber(a,b),至此,完成修订功能,也完成装饰器全部过程。原系统还是执行h=sqrt(calNumber(3,5)),其结构不变,新增功能也完全实现。
二、带参数的装饰器
当然,例子中假定的新增功能比较简单,运用的还是原函数中的参数,假定实际工作中又有新的需求,需要对计算结果与输入参数进行大小比较,输出最大值。即:原结果为3+5=8,要用8去跟某一参数比较后输出较大者,我们也可以用装饰器来实现:
def cmpCal(d):
def newCal(func):
def wrapF(a,b)
a=abs(a)
b=abs(b)
return max(func(a,b),d) #将计算结果与d做比较后输出
return wrapF
return newCal
#在@cmpCal后面添加所需参数。
@cmpCal(d)
def calNumber(a,b):
c=a+b
return c
h=sqrt(calNumber(3,5))
print(h)
至此,装饰器的基本用法介绍完毕,至于组合装饰器实现原理也差不多,大家去看书学习吧。
浙公网安备 33010602011771号