- 装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能
- 两个原则:
不能修改被装饰的函数的源代码
不能修改被装饰的函数的调用方式
对无参函数进行装饰
def total_time(func):
def wrapper():
start = datetime.datetime.now()
func()
stop = datetime.datetime.now()
time = (stop - start).seconds
print(time)
return wrapper
@total_time
def pri():
print("计算程序执行时间")
if __name__ == "__main__":
pri()
# #原理:
1.执行函数pri()时,会先调用total_time函数,将被装饰的函数pri当做入参传入(此时未pri)
2.在执行total_time函数时,直接把内部函数wrapper返回了,同时把它赋值给pri
3.(重点)此时的pri已经不是未加装饰时的pri了,而是指向了total_time.wrapper函数地址了
4.接下来,执行新pri函数,即total_time.wrapper函数,先start赋值,然后调用原来的pri(),该处的pri就是通过装饰传进来的参数pri
对有参函数进行装饰
def total_time(func):
def wrapper(*args,**kwargs):
start = datetime.datetime.now()
func(*args,**kwargs)
stop = datetime.datetime.now()
time = (stop - start).seconds
print(time)
return wrapper
@total_time
def pri(a,b,c):
print("计算程序执行时间")
print(a+b+c)
if __name__ == "__main__":
pri(1,2,3)
两个装饰器
def makeBold(fun):
print('----a----')
def inner1():
print('----1----')
return '' + fun() + ''
return inner1
def makeItalic(fun):
print('----b----')
def inner2():
print('----2----')
return '' + fun() + ''
return inner2
@makeBold
@makeItalic
def test():
print('----c----')
print('----3----')
return 'hello python decorator'
test()
输出:
----b----
----a----
----1----
----2----
----c----
----3----
hello python decorator
原理:
1.在执行@makeBold时,对下面的函数进行装饰,发现并不是一个函数名,而又是一个装饰器,@makeBold装饰器暂停执行,而接着执行接下来的装饰器@makeItalic
2.把函数test当成参数传入装饰器函数makeItalic,打印"b",在makeItalic装饰完后,此时的test指向makeItalic的inner2函数地址
3.(关键)这时会返回来执行@makeBold,接着把新test传入makeBold装饰器函数中,因此打印了'a',接着返回inner1,打印“1”
4.(关键)然后此时的fun()即是新test,即指向makeItalic的inner2函数地址,打印“2”,此时的inner2中,调用的fun其实才是我们最原生的test函数,打印c,3
5.然后hello python decorator,然后hello python decorator
参考资料:https://www.jb51.net/article/158814.htm