无惧面试,带你搞懂python装饰器

  

<强>写在之前

  

"装饰器”作为Python高级语言特性中的重要部分,是修改函数的一种超级便捷的方式,适当使用能够有效提高代码的可读性和可维护性,非常的便利灵活。

  “本

"装饰器质上就是一个函数,这个函数的特点是可以接受其它的函数当作它的参数,并将其替换成一个新的函数(即返回给另一个函数)。

  

可能现在这么看的话有点懵,为了深入理解“装饰器”的原理,我们首先先要搞明白”什么是函数对象”,“什么是嵌套函数”,“什么是闭包”。关于这三个问题我在很久以前的文章中已经写过了,你只需要点击下面的链接去看就好了,这也是面试中常问的知识哦:

  https://www.jb51.net/article/158738.htm

  

<>强装饰器

  

搞明白上面的三个问题,其实简单点来说就是告诉你:函数可以赋值给变量,函数可嵌套,函数对象可以作为另一个函数的参数。

  

首先我们来看一个例子,在这个例子中我们用到了前面列出来的所有知识:

        def第一(有趣的):   def第二():   打印(“开始”)   有趣的()   print(结束)   打印fun.__name__   返回第二个      def人():   打印(“我一个人()”)      f=第一(人)   f ()      

上述代码的执行结果如下所示:

  
  


开始   我是一个男人()
  
结束   人

     

上面的程序中,这个就是第一个函数接收了人函数作为参数,并将人函数以一个新的函数进行替换。看到这你有没有发现,这个和我在文章刚开始时所说的“装饰器”的描述是一样的。既然这样的话,那我们就把上述的代码改造成符合Python装饰器的定义和用法的样子,具体如下所示:

        def第一(函数):   def第二():   打印(“开始”)   函数()   print(结束)   打印(func.__name__)   返回第二个      @first   def人():   打印(“我一个人()”)      人()      

上面这段代码和之前的代码的作用一模一样区。别在于之前的代码直接“明目张胆”的使用第一个函数去封装人函数,而上面这个是用了“语法糖”来封装人函数。至于什么是语法糖,不用细去追究,你就知道是类似“@first”这种形式的东西就好了。

  

在上述代码中“@frist”在人函数的上面,表示对人函数使用第一个装饰器。“@”是装饰器的语法,“第一”是装饰器的名称。

  

下面我们再来看一个复杂点的例子,用这个例子我们来更好的理解一下“装饰器”的使用以及它作为Python语言高级特性被人津津乐道的部分:

        def check_admin(用户名):   如果用户名!=肮芾怼?   提高异常(“该用户没有权限”)      类堆栈:   def __init__(自我):   自我。项=[]      def推(自我、用户名、项目):   check_admin(用户名=用户名)   self.item.append(项)      def流行(自我、用户名):   check_admin(用户名=用户名)   如果不是self.item:   提高异常(“没有elem堆栈”)   返回self.item.pop ()      

上述实现了一个特殊的栈,特殊在多了检查当前用户是否为管理这步判断,如果当前用户不是管理员,则抛出异常上。面的代码中将检查当前用户的身份写成了一个独立的函数check_admin,在推动和流行中只需要调用这个函数即可。这种方式增强了代码的可读性,减少了代码冗余,希望大家在编程的时候可以具有这种意识。

  

下面我们来看看上述代码用装饰器来写成的效果:

        def check_admin(函数):   def包装器(* args, * * kwargs):   如果kwargs.get(“用户名”)!=肮芾怼?   提高异常(“该用户没有权限”)   返回func (* args, * * kwargs)   返回包装      类堆栈:   def __init__(自我):   自我。项=[]      @check_admin   def推(自我、用户名、项目):   self.item.append(项)      @check_admin   def流行(自我、用户名):   如果不是self.item:   提高异常(“没有elem堆栈”)   返回self.item.pop ()      

对比一下使用“装饰器”和不使用装饰器的两种写法,乍一看,好像使用“装饰器”以后代码的行数更多了,但是你有没有发现代码看起来好像更容易理解了一些。在没有装饰器的时候,我们先看到的是check_admin这个函数,我们得先去想这个函数是干嘛的,然后看到的才是对栈的操作,而使用装饰器的时候,我们上来看到的就是对栈的操作语句,至于check_admin完全不会干扰到我们对当前函数的理解,所以使用了装饰器可读性更好了一些。

无惧面试,带你搞懂python装饰器