装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。

装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。

概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

Python的 装饰器(decorator) 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。

使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码。

 

#!/usr/bin/env python


def outer(func):
    print('这是outer。')

    def inner():
        print('这是inner。')
        func()
        print('这是最后。')
    return inner


@outer
def f1():
    print('这是F1。')

f1()

  

详细说说这段代码的执行过程。

  • 代码从上到下执行,先将outer函数和f1函数载入内存,然后调用f1()
  • 在f1函数前一行加@outer表示调用outer装饰器
  • 执行f1函数时,将函数名f1当作参数传入装饰器outer,并执行outer
  • 装饰器outer的参数func其实就是函数f1,而outer的返回值inner将赋值给f1,所以“rerurn inner”这句代码必不可少,而原来的f1将被inner取代
  • 执行装饰器outer先输出“这是outer。”,下面在执行函数inner(inner其实就是新的f1),输出"这是inner。" , 然后执行func函数,func实际上就是上一步传入的f1,所以执行func()就是执行原函数f1(),所以输出”这是F1。“, 然后再输出"这是最后。"

此执行过程需不断体会方能领悟。

如果暂时无法领悟,可以理解为装饰器就是给函数做了一个装饰,让这个函数在执行之前或者执行之后或者执行前后可以做一些其他事情。

 

另外,装饰器可以带参数、一个函数可以有多个装饰器。