python里的函数装饰器是利用闭包实现的,实现了对函数功能的补充。
def deco(func):
def wrapper():
print("---开始装饰函数--")
func()
print("---结束函数装饰")
return wrapper
@deco
def sayHello():
print("Say Hello")
sayHello()
@deco就是给sayHello函数加了装饰器,在执行sayHello()的时候输出的结果如下。轻松的完成了对sayHello函数这个功能的补充。
---开始装饰函数--
Say Hello
---结束函数装饰
注意:@deco这句被解释器读到的时候,其实deco函数就已经被执行了一次。下面的代码并没有显式地调用任何函数,但是执行这一段代码的时候,依然会有输出。
def deco(func):
print("--我是deco函数输出的第一句话")
def wrapper():
print("---开始装饰函数--")
func()
print("---结束函数装饰")
print("---deco函数运行结束---")
return wrapper
@deco
def sayHello():
print("Say Hello")
输出结果:
--我是deco函数输出的第一句话
---deco函数运行结束---
多个装饰器的执行顺序:
def deco1(func):
print("--我是deco1函数输出的第一句话")
def wrapper():
print("---deco1:开始装饰函数--")
func()
print("---deco1:结束函数装饰")
print("---deco1函数运行结束---")
return wrapper
def deco2(func):
print("--我是deco2函数输出的第一句话")
def wrapper():
print("---deco2:开始装饰函数--")
func()
print("---deco2:结束函数装饰")
print("---deco2函数运行结束---")
return wrapper
@deco1
@deco2
def sayHello():
print("Say Hello")
执行结果:(装饰器由下到上开始加载)
--我是deco2函数输出的第一句话
---deco2函数运行结束---
--我是deco1函数输出的第一句话
---deco1函数运行结束---
调用上面被两个装饰器装饰的函数sayHello()的执行结果:装饰器是从上到下开始装饰,正好和加载的顺序相反。
---deco1:开始装饰函数--
---deco2:开始装饰函数--
Say Hello
---deco2:结束函数装饰
---deco1:结束函数装饰
装饰带参数的函数:(用不定长参数的格式可以满足不同参数列表的函数的装饰)
def decoFunc(func):
def wrapper(*args,**kargs):
print('---开始装饰--')
func(*args,**kargs)
print('---结束装饰---')
return wrapper
@decoFunc
def testFunc1():
print('---我是一个无参数且需要被装饰的函数---')
@decoFunc
def testFunc2(name,age):
print('---我是一个带参数的需要被装饰的函数----')
print('---name:' + str(name) + '--age:' + str(age))
testFunc1()
print('-----漂亮的分割线---')
testFunc2('小明',15)
装饰带返回值的函数:装饰器内部函数亦返回结果即可。
def decoFunc(func):
def wrapper(*args,**kargs):
print('---开始装饰--')
returnValue =func(*args,**kargs)
print('---结束装饰---')
return returnValue
return wrapper
@decoFunc
def testFunc1():
print('---我是一个无参数且需要被装饰的函数---')
return 1
@decoFunc
def testFunc2(name,age):
print('---我是一个带参数的需要被装饰的函数----')
print('---name:' + str(name) + '--age:' + str(age))
return name
testFunc1()
print('-----漂亮的分割线---')
testFunc2('小明',15)
带参数的装饰器:(比普通的装饰器再多加一层即可,注意每一层的返回值。)
def deco_arg(name):
print("name is:" + name)
def deco(func):
def wrapper():
print("--"+name+"--开始装饰--")
func()
return wrapper
return deco
@deco_arg("王小二")
def test():
print("--我是需要被装饰的函数")
test()
输出结果:
name is:王小二
--王小二--开始装饰--
--我是需要被装饰的函数