无惧面试,带你搞懂python 装饰器
写在之前
「装饰器」作为Python高级语言特性中的重要部分,是修改函数的一种超级便捷的方式,适当使用能够有效提高代码的可读性和可维护性,非常的便利灵活。
「装饰器」本质上就是一个函数,这个函数的特点是可以接受其它的函数当作它的参数,并将其替换成一个新的函数(即返回给另一个函数)。
可能现在这么看的话有点懵,为了深入理解「装饰器」的原理,我们首先先要搞明白「什么是函数对象」,「什么是嵌套函数」,「什么是闭包」。关于这三个问题我在很久以前的文章中已经写过了,你只需要点击下面的链接去看就好了,这也是面试中常问的知识哦:
https://www.nhooo.com/article/158738.htm
装饰器
搞明白上面的三个问题,其实简单点来说就是告诉你:函数可以赋值给变量,函数可嵌套,函数对象可以作为另一个函数的参数。
首先我们来看一个例子,在这个例子中我们用到了前面列出来的所有知识:
deffirst(fun): defsecond(): print('start') fun() print('end') printfun.__name__ returnsecond defman(): print('iamaman()') f=first(man) f()
上述代码的执行结果如下所示:
start
iamaman()
end
man
上面的程序中,这个就是first函数接收了man函数作为参数,并将man函数以一个新的函数进行替换。看到这你有没有发现,这个和我在文章刚开始时所说的「装饰器」的描述是一样的。既然这样的话,那我们就把上述的代码改造成符合Python装饰器的定义和用法的样子,具体如下所示:
deffirst(func): defsecond(): print('start') func() print('end') print(func.__name__) returnsecond @first defman(): print('iamaman()') man()
上面这段代码和之前的代码的作用一模一样。区别在于之前的代码直接“明目张胆”的使用first函数去封装man函数,而上面这个是用了「语法糖」来封装man函数。至于什么是语法糖,不用细去追究,你就知道是类似「@first」这种形式的东西就好了。
在上述代码中「@frist」在man函数的上面,表示对man函数使用first装饰器。「@」是装饰器的语法,「first」是装饰器的名称。
下面我们再来看一个复杂点的例子,用这个例子我们来更好的理解一下「装饰器」的使用以及它作为Python语言高级特性被人津津乐道的部分:
defcheck_admin(username): ifusername!='admin': raiseException('Thisuserdonothavepermission') classStack: def__init__(self): self.item=[] defpush(self,username,item): check_admin(username=username) self.item.append(item) defpop(self,username): check_admin(username=username) ifnotself.item: raiseException('NOeleminstack') returnself.item.pop()
上述实现了一个特殊的栈,特殊在多了检查当前用户是否为admin这步判断,如果当前用户不是admin,则抛出异常。上面的代码中将检查当前用户的身份写成了一个独立的函数check_admin,在push和pop中只需要调用这个函数即可。这种方式增强了代码的可读性,减少了代码冗余,希望大家在编程的时候可以具有这种意识。
下面我们来看看上述代码用装饰器来写成的效果:
defcheck_admin(func): defwrapper(*args,**kwargs): ifkwargs.get('username')!='admin': raiseException('Thisuserdonothavepermission') returnfunc(*args,**kwargs) returnwrapper classStack: def__init__(self): self.item=[] @check_admin defpush(self,username,item): self.item.append(item) @check_admin defpop(self,username): ifnotself.item: raiseException('NOeleminstack') returnself.item.pop()
对比一下使用「装饰器」和不使用装饰器的两种写法,乍一看,好像使用「装饰器」以后代码的行数更多了,但是你有没有发现代码看起来好像更容易理解了一些。在没有装饰器的时候,我们先看到的是check_admin这个函数,我们得先去想这个函数是干嘛的,然后看到的才是对栈的操作;而使用装饰器的时候,我们上来看到的就是对栈的操作语句,至于check_admin完全不会干扰到我们对当前函数的理解,所以使用了装饰器可读性更好了一些。
就和我在之前的文章中所讲的「生成器」那样,虽然Python的高级语言特性好用,但也不能乱用。装饰器的语法复杂,通过我们在上面缩写的装饰器就可以看出,它写完以后是很难调试的,并且使用「装饰器」的程序的速度会比不使用装饰器的程序更慢,所以还是要具体场景具体看待。
以上就是无惧面试,带你搞懂python装饰器的详细内容,更多关于python装饰器的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。