主要是为了实现装饰器的功能
装饰器:对原函数进行修饰,不改变原函数的调用方法和代码,但是经过装饰之后,可以改变原函数的功能。
装饰器=高阶函数+闭包+函数嵌套
对于一个函数,实现装饰器功能的过程,。
原函数:
import time def test(): time.sleep(1) print('这个是原函数')
目的:对这个函数进行修饰,在进行调用的时候,可以显示这个函数运行了多长时间。
如果仅使用高阶函数,进行修改。
#仅使用高阶函数来实现 import time def test(): time.sleep(1) print('这个是原函数') #对这个函数进行修饰,显示原函数运行的时间 def wrapper(func): start_time=time.time() func() end_time=time.time() shijian=end_time-start_time print('运行时间是%s' %shijian) return func test=wrapper(test) test()
运行结果会出现问题:
在运行test=wrapper(test)的时候,wrapper函数已经开始运行,然后再次运行test()的时候,原函数就会再运行一次,所以,就没有实现装饰器的功能。
2.在高阶函数的基础上加上闭包和嵌套
#仅使用高阶函数来实现 import time def test(): time.sleep(1) print('这个是原函数') #对这个函数进行修饰,显示原函数运行的时间 def zhuangshiqi(func): def wrapper(): start_time=time.time() func() end_time=time.time() shijian=end_time-start_time print('运行时间是%s' %shijian) return wrapper test=zhuangshiqi(test) test()
上面简单的实现了装饰器的功能。在test=zhuangsihqi()的时候,代码只是进行了: return wrapper这个动作,函数并没有运行,在test()的时候,函数才正式运行
和只使用高阶函数相比,使用了嵌套和闭包,这样的话,在给test传值的时候,函数就不会运行,影响原函数的功能。
3.对于有return的原函数进行修改
#仅使用高阶函数来实现 import time def test(): time.sleep(1) print('这个是原函数') return 'abc' #对这个函数进行修饰,显示原函数运行的时间 def zhuangshiqi(func): def wrapper(): start_time=time.time() a=func() end_time=time.time() shijian=end_time-start_time print('运行时间是%s' %shijian) return a return wrapper test=zhuangshiqi(test) test() b=test() print(b)
对于原函数,test来说,可以有无数种return,所以装饰器内,需要通过一个参数,来变化的接收test函数中的ruturn,然后在return回去,
4.对于原函数有参数的情况下
#仅使用高阶函数来实现 import time def test(x,y): time.sleep(1) print('这个是原函数') return x+y #对这个函数进行修饰,显示原函数运行的时间 def zhuangshiqi(func): def wrapper(*args,**kwargs): start_time=time.time() a=func(*args,**kwargs) end_time=time.time() shijian=end_time-start_time print('运行时间是%s' %shijian) return a return wrapper test=zhuangshiqi(test) test(3,5) b=test(3,5) print(b)
使用*args来接收除字典外的值,使用**kwargs来接收字典,这两个组合可以接收不定长的参数。
在自己的分析中,test=zhuangshiqi(test)的时候,其实就是把test当做一个参数,放入wrapper当中,所以wrapper的参数要和test的参数一样,在wrapper当中,func其实就是wrapper,所以参数也必须一样,其实就是把参数传过去