Python 装饰器这东西对初学者来说是个坑,很容易绕晕,笔者当时初学装饰器时花费了数天时间,看了不同讲师对这块内容的讲解,还是一知半解。
不过装饰器在开发中可是很好用的,有必要攻破,希望这篇文章能帮助学习者快速攻破难关。
初步理解
# 先来看一个简单函数
def show():
print ('Mr tu')
show()
# 执行结果 :
Mr tu
# 现在我们用装饰器扩展这个函数,在打印 " Mr tu " 之前打印一行 " hello "
def decorate(fun1):
def wapper():
print('hello')
fun1()
return wapper
@decorate
def show():
print ('Mr tu')
show()
# 执行结果 :
hello
Mr tu
# 现在解释上面的代码。
# 1、首先 def decorate(fun1) 定义一个装饰器函数,在此函数里又定义了一个wapper子函数,子函数可以继承父函数的参数。
# 2、 @'函数名'是Python的一种语法糖 @decorate 等于 decorate(show)
# 还是晕,不明白? 没关系,看下面代码:
def decorate(fun1):
def wapper():
print('hello')
fun1()
return wapper
def show():
print ('Mr tu')
f1 = decorate(show)
f1()
# 执行结果 :
hello
Mr tu
# 换成这种写法,执行效果是一样的,因为这就是 @decorate 的本质。
# 就是将被装饰器装饰的函数show作为参数传给装饰器函数。
# 总结执行过程:
# 1、show函数作为参数传给装饰器函数 decorate ,那么 fun1 = show
# 2、这时执行到装饰器的子函数 wapper,子函数可以继承父函数的参数,所以可以调用 fun1
# 3、然后wapper函数执行 print 打印一行 "hello" , 再然后 调用fun1() —— 这里其实就是执行了show函数。 因为在装饰器一开始执行的时候就把show函数作为参数赋值给了fun1.
# 现在明白了吧,只要这里明白,下面的就很好理解了。
装饰带参数的函数
# 一个参数
def decorate(fun1):
def wapper(arg1):
print('hello')
fun1(arg1)
print('nice to meet you')
return wapper
@decorate
def show(arg1):
print (arg1)
show('Mr Alice')
# 执行结果:
hello
Mr Alice
nice to meet you
# 两个参数
def decorate(fun1):
def wapper(arg1,arg2):
print('hello')
fun1(arg1,arg2)
print('nice to meet you')
return wapper
@decorate
def show(arg1,arg2):
print (arg1,arg2)
show('Mr Alice','Mr Tom')
# 执行结果:
hello
('Mr Alice', 'Mr Tom')
nice to meet you
# n个参数
def decorate(fun1):
def wapper(*args,**kwargs):
print('hello')
fun1(*args,**kwargs)
print('nice to meet you')
return wapper
@decorate
def show(*args,**kwargs):
print (args[0])
print (args[1])
print (args[2])
show('Mr Alice','Mr Tim','Mr tu')
# 执行结果:
hello
Mr Alice
Mr Tim
Mr tu
nice to meet you
一个函数被多个装饰器装饰
def decorate01(fun1):
def wapper(*args,**kwargs):
print('hello world')
print('I am decorate01')
fun1(*args,**kwargs)
return wapper
def decorate02(fun1):
def wapper(*args,**kwargs):
print ('I am decorate02')
fun1(*args,**kwargs)
print('nice to meet you')
return wapper
@decorate01
@decorate02
def show(*args,**kwargs):
print (args[0])
print (args[1])
print (args[2])
show('Mr Alice','Mr Tim','Mr tu')
# 执行结果:
hello world
I am decorate01
I am decorate02
Mr Alice
Mr Tim
Mr tu
nice to meet you
# 观察print放置的位置不同,对应的输出结果不同。
def decorate01(fun1):
def wapper(*args,**kwargs):
print('hello world')
fun1(*args,**kwargs)
print('I am decorate01') # 替换到了下面
return wapper