(转)python里为什么需要使用装饰器(decorator)
Posted goyier
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(转)python里为什么需要使用装饰器(decorator)相关的知识,希望对你有一定的参考价值。
为什么需要使用装饰器呢?其实很多人学习python之后都会问这个问题。
这一次,我来深入地学习一下什么是装饰器,以及为什么需要它。
其实这个装饰器就是我们这样的程序员太“懒”了,基本上什么事情都想少做,追求是DRY,那么什么是DRY,如下:
DRY(Don‘t repeat yourself
),字面意思来看:"不要重复自己"。强调的意思就是在进行编程时相同的代码不要重复写,最好只写一次,然后可以在其他地方直接引用。如此一来,可以提高代码重用率,缩减代码量,同时也有助于提高代码的可读性和可维护性。当需要做出更改时,只需要更改一个地方即可。
有了这个指导思想,就很明白了,就是少写代码,装饰器的目的也就是少写代码,复用代码。
复用代码有很多种方式,比如面向对象里的继承,虚函数等,但是想在函数层面来复用代码,有什么方法呢?
一般情况之下,就是函数中调用另一个函数来达到继承和复用。函数里调用别的函数,如下面的例子:
1 #python 3.6 2 def add(): 3 return 1 + 1 4 5 def sub(): 6 return 2 -1 7 8 print(add()) 9 print(sub())
输出如下:
2
1
如果这时,我们想把每个函数添加一行星号打印输出,以便分隔开来,更好看一些,我们往往会这样做修改,
每个函数里添加一行星号就行了,修改如下:
1 #python 3.6 2 def add(): 3 print(‘*************************************‘) 4 return 1 + 1 5 6 def sub(): 7 print(‘*************************************‘) 8 return 2 -1 9 10 print(add()) 11 print(sub())
输出如下:
*************************************
2
*************************************
1
当我们只有两个函数时,这样修改很快的,并且很快就完成工作了,但是如果有1000个这样函数呢?那么是否需要添加1000遍?
如果你每个函数去添加一个也是可以完成任务的,但是有想法,或者更聪明的办法,就不是这样了。能否不修改原来的函数,即是原来的函数代码一点都不改变,又能增加这样的功能呢?答案是可以的,如下修改:
1 #python 3.6 2 def add(): 3 return 1 + 1 4 5 def sub(): 6 return 2 -1 7 8 #定义一个新的函数 9 def printStar(func): 10 print(‘*************************************‘) 11 return func() 12 13 print(printStar(add)) 14 print(printStar(sub))
输出如下:
*************************************
2
*************************************
1
在这里增加了一个函数,这个函数接收一个函数对象作为参数,这样就不需要修改原来的函数,达到原来稳定并且测试通过的代码不作任何修改,减少出错的风险,特别已经上线运行的系统,更是如此;或者像8代单传的代码,没有人敢去修改它,否则领导会怪你,怎么样把产品越改越差,本来是请你来做好产品的,结果不行。做到这一步,就结束了吗?还不行啊,因为每个调用这个函数的地方都需要修改,因此再继续修改,结果改成这样:
1 #python 3.6 2 #定义一个新的函数 3 def printStar(func): 4 print(‘*************************************‘) 5 return func() 6 7 @printStar 8 def add(): 9 return 1 + 1 10 11 def sub(): 12 return 2 -1 13 14 15 16 print(add) 17 print(printStar(sub))
输出结果如下:
*************************************
2
*************************************
1
这里发现调用add方法,还是不一样,继续修改,代码如下:
1 #python 3.6 2 #定义一个新的函数 3 def printStar(func): 4 def f(): 5 print(‘*************************************‘) 6 return func() 7 return f 8 9 @printStar 10 def add(): 11 return 1 + 1 12 13 def sub(): 14 return 2 -1 15 16 print(add()) 17 18 sub = printStar(sub) 19 print(sub())
输出结果如下:
*************************************
2
*************************************
1
到这里,可以发现使用嵌套函数来实现,就可以返回一个可调用的对象,这样更加完美了。
1 #python 3.6 2 #定义一个新的函数 3 def printStar(func): 4 def f(): 5 print(‘*************************************‘) 6 return func() 7 return f 8 9 @printStar 10 def add(): 11 return 1 + 1 12 13 @printStar 14 def sub(): 15 return 2 -1 16 17 print(add()) 18 19 print(sub())
在这里可以发现这两段代码是相等的:
def sub():
return 2 -1
sub = printStar(sub)
和
@printStar
def sub():
return 2 -1
由此可见@printStar是一个语法改变,它的目标就是实现不修改原来函数的代码,又可以复用原来的函数并且作出修改,也称作为元编程,并且装饰器函数可以复用,实现共享的目标。
以上是关于(转)python里为什么需要使用装饰器(decorator)的主要内容,如果未能解决你的问题,请参考以下文章