深入了解和应用Python装饰器@decorator

  

深入了解和应用Python装饰器@decorator

  

Python的装饰器(decorator)是一个很棒的机制,也是熟练运用Python的必杀技之一。装饰器,顾名思义,就是用来装饰的,它装饰的是一个函数,保持被装饰函数的原有功能,再装饰上(添油加醋)一些其它功能,并返回带有新增功能的函数对象,所以装饰器本质上是一个返回函数对象的函数(确切的说,装饰器应该是可调用对象,除了函数,类也可以作为装饰器)。

  

在编程过程中,我们经常遇到这样的场景:登录校验,权限校验,日志记录等,这些功能代码在各个环节都可能需要,但又十分雷同,通过装饰器来抽象,剥离这部分代码可以很好解决这类场景。

  

  

要理解Python的装饰器,首先我们先理解一下Python的函数对象。我们知道,在Python里一切都是对象,函数也不例外,函数是第一类对象(一流的对象),它可以赋值给变量,也可以作为列表的元素,还可以作为参数传递给其它函数。

  

<强>函数可以被变量引用

  

定义一个简单的函数:
  

        def say_hi ():   打印(“嗨!”)   say_hi ()   #输出:嗨!      

个变量say_hi2来引用say_hi函数:
  

        say_hi2=say_hi   打印(say_hi2)   #输出:& lt;函数say_hi 0 x7fed671c4378>      say_hi2 ()   #输出:嗨!      

上面的语句中say_hi2和say_hi指向了同样的函数定义,二者的执行结果也相同。

  

<强>函数可以作为参数传递给其它函数
  

        def say_more (say_hi_func):   打印(更多的)   say_hi_func ()      say_more (say_hi)   #输出:   #更多   #嗨   之前      

在上面的例子中,我们把say_hi函数当做参数传递给say_more函数,say_hi被变量say_hi_func引用。

  

<强>函数可以定义在其它函数内部
  

        def say_hi ():   打印(“嗨!”)   def say_name ():   打印(‘汤姆’)   say_name ()      say_hi ()   #输出:   #你好!   #汤姆      say_name() #报的错   之前      

上述代码中,我们在say_hi()函数内部定义了另外一个函数say_name () .say_name()只在say_hi函数内部可见(即,它的作用域在say_hi函数内部),在say_hi外包调用时就会出错。

  

<强>函数可以返回其它函数的引用
  

        def say_hi ():   打印(“嗨!”)   def say_name ():   打印(‘汤姆’)   返回say_name      say_name_func=say_hi ()   #打印嗨!,并返回say_name函数对象   #并赋值给say_name_func      say_name_func ()   #打印汤姆   之前      

上面的例子,say_hi函数返回了其内部定义的函数say_name的引用。这样在say_hi函数外部也可以使用say_name函数了。

  

前面我们理解了函数,这有助于我们接下来弄明白装饰器。

  

<>强装饰器(Decorator)

  

装饰器是可调用对象(可调用的对象),它用来修改函数或类。
  可调用对象就是可以接受某些参数并返回某些对象的对象.Python里的函数和类都是可调用对象。

  

函数装饰器,就是接受函数作为参数,并对函数参数做一些包装,然后返回增加了包装的函数,即生成了一个新函数。

  

让我们看看下面这个例子:
  

        def decorator_func (some_func):   #定义另一个包装器函数,修改some_func   def wrapper_func ():   打印(“包装器函数开始”)      some_func ()      print(“包装器函数结束”)      返回wrapper_func #包装器函数通过添加一些功能和装饰返回包装器函数      def say_hello ():   打印(“Hello”)      say_hello=decorator_func (say_hello)      say_hello ()      #输出:   #包装器函数开始   #你好   #包装器函数结束了      

上面例子中,decorator_func就是定义的装饰器函数,它接受some_func作为参数。它定义了一个wrapper_func函数,该函数调用了some_func但也增加了一些自己的代码。

  

上面代码中使用装饰器的方法看起来有点复杂,其实真正的装饰器的Python语法是这样的:

深入了解和应用Python装饰器@decorator