装饰器

装饰器的原理

1. 函数可作为对象传递

理解函数的传递是理解装饰器的基础,python中一切皆对象,因此一切可传递。

假设有俩个函数,A和B;
其中A作为参数传给函数B(注意,函数作为参数传递时,不能带'()',表示引用);
现在让函数B再把函数A返回,然后赋值给一个变量c,看c是否指向了函数A,写代码试下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
def A():
    print('函数A已执行')

def B(func):  # 接收函数func
    print('函数B已执行')
    return func  # 返回函数func

c = B(A)  
#调用函数B,其结果赋值给变量c
#输出:函数B已执行

c() 
#调用变量c
#输出:函数A已执行
#说明变量c指向了函数A

2. 装饰器

现在我们理解了函数的传递,接下来写个稍微有用点的程序。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#a_decorator接收一个函数a_func,
# 并返回另一个函数wrapTheFunction。
def a_decorator(a_func):  
    def wrapTheFunction():  
    #在wrapTheFunction中,
    #对调用a_func的前后做了控制,
    #本例是在其前后各打印一句话。
        print('before executing a_func')
        a_func()
        print('after executing a_func')

    return wrapTheFunction  

def a_function():
    print('i am a function')

a_function = a_decorator(a_function)  
#函数a_function的同名变量a_function,
#获得了函数a_decorator的返回值,
#即指向了wrapTheFunction函数。

a_function()
#输出:before executing a_func
#     i am a function
#     after executing a_func
#说明变量a_function指向了wrapTheFunction函数

那么,装饰器的作用就是如上,在函数a_function执行前后做一些控制,@xxx的形式不过是一种简写,如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
def a_decorator(a_func):  
    def wrapTheFunction(): 
        print('before executing a_func')
        a_func()
        print('after executing a_func')

    return wrapTheFunction  

@a_decorator
def a_function()
    print('i am a function')

a_function()  
#添加@a_decorator后,
#表示使用函数a_decorator控制函数a_function,
#a_function = a_decorator(a_function) 
#就不用写了~
#输出:before executing a_func
#     i am a function
#     after executing a_func