最近在Python中遇到了修饰器(decorator)这个概念,一直不是十分理解。在看了python装饰器详解这篇博客后,对其的概念和用法有了一个大致的认识。但是,博客的最后一个例子我还是没有能够正确写出执行结果。因此我又自己写了一个多层修饰器的例子。以下是我对执行过程的理解。
# an example of python decorator
def deco1(func):
print(1)
def wrapper1():
print(2)
func()
print(3)
print(4)
return wrapper1
def deco2(func):
print(5)
def wrapper2():
print(6)
func()
print(7)
print(8)
return wrapper2
@deco1
@deco2
def foo():
print('foo')
if __name__ == '__main__':
foo()
运行结果:
5
8
1
4
2
6
foo
7
3
- 修饰器本质上就是一个函数,只不过它的传入参数同样是一个函数。因此,依次加了
deco1
和deco2
两个装饰器的原函数foo实际上相当于deco1(deco2(foo))
。 - 明白了第1步后,下面进入这个复合函数。首先执行的是内层函数
deco2(foo)
。因此第一个打印值是5。接下来要注意,在deco2
这个函数内定义了一个wrapper2
函数,但是并没有类似于wrapper2()
的语句,因此该函数内的语句并没有立即执行,而是作为了返回值。因此wrapper2
内的3条语句作为输入参数传递到了deco1
内。wrapper2
函数内还有一行print(8)
,因此第二个打印值为8。 - 下一步是执行
deco1()
函数内容。与2类似,先打印出1和4,返回值为wrapper1
。由于更外层没有装饰器,因此接下来就将执行wrapper1
内的内容。第五个打印值为2。接着执行func()
函数,注意此处func()
表示的是wrapper2
中的内容,因此跳到wrapper2
中执行。第六个打印值为6。类似的,wrapper2
中的func()
为foo()
,因此接着会输出foo。最后,回到wrapper2
和wrapper1
的最后一行,依次输出7和3。到这里,整个装饰器的运行过程结束。