装饰器:本质就是函数,功能是为其他函数添加功能;
原则:
1、不修改被修饰函数的源代码
2、不修改被修饰函数的调用方式
装饰器的只是储备:
装饰器=高阶函数+函数嵌套+闭包
高阶函数的定义:1、函数接受的参数是一个函数名;2、函数的返回值是一个函数名;3、满足上述条件任意一个,都可称之为高阶函数;
高阶函数:
import time def foo(): time.sleep(1) print('来自foo') def timer(func): start_time=time.time() func() end_time=time.time() print('运行时间是%s'%(end_time-start_time)) return func foo=timer(foo) foo()
函数嵌套(闭包):
def father(auth_type): # print('from father %s' %name) def son(): # name='linhaifeng_1' # print('我的爸爸是%s' %name) def grandson(): print('我的爷爷是%s' %auth_type) grandson() # print(locals()) son() # father('linhaifeng') father('filedb')
所以,装饰器的架构:
import time def timmer(func): #func=test #func满足参数是函数名 def wrapper(): # print(func) start_time=time.time() func() #就是在运行test() stop_time = time.time() print('运行时间是%s' %(stop_time-start_time)) return wrapper #warpper满足返回值是一个函数名 @timmer #test=timmer(test) def test(): time.sleep(3) print('test函数运行完毕') test() # res=timmer(test) #返回的是wrapper的地址 # res() #执行的是wrapper() # test=timmer(test) #返回的是wrapper的地址 # test() #执行的是wrapper() # @timmer 就相当于 test=timmer(test)
改进:由于test()运行完后没有返回值,会输出一个None
import time def timmer(func): #func=test #func满足参数是函数名 def wrapper(): # print(func) start_time=time.time() res=func() #就是在运行test() stop_time = time.time() print('运行时间是%s' %(stop_time-start_time)) return res return wrapper #warpper满足返回值是一个函数名 @timmer #test=timmer(test) def test(): time.sleep(3) print('test函数运行完毕') return '这是test的返回值' res=test() print(res)
加上参数:
import time def timmer(func): #func=test1 def wrapper(*args,**kwargs): #test('linhaifeng',age=18) args=('linhaifeng') kwargs={'age':18} #解压序列,此处只能解压出三个参数; start_time=time.time() res=func(*args,**kwargs) #就是在运行test() func(*('linhaifeng'),**{'age':18}) stop_time = time.time() print('运行时间是%s' %(stop_time-start_time)) return res return wrapper # @timmer #test=timmer(test) def test(name,age): time.sleep(3) print('test函数运行完毕,名字是【%s】 年龄是【%s】' %(name,age)) return '这是test的返回值' @timmer def test1(name,age,gender): time.sleep(1) print('test1函数运行完毕,名字是【%s】 年龄是【%s】 性别【%s】' %(name,age,gender)) return '这是test的返回值' # res=test('linhaifeng',age=18) #就是在运行wrapper # # print(res) # test1('alex',18,'male') test1('alex',18,'male') # def test2(name,age,gender): #test2(*('alex',18,'male','x','y'),**{}) # #name,age,gender=('alex',18,'male','x','y') # print(name) # print(age) # print(gender) # # def test1(*args,**kwargs): # test2(*args,**kwargs) #args=('alex',18,'male','x','y') kwargs={} # # # test2('alex',18,gender='male') # # test1('alex',18,'male')
装饰器的实现,运行步骤:
import time #1 def timmer(func): #func=test #func满足参数是函数名 #2 def wrapper(): #6 # print(func) start_time=time.time() #7 func() #就是在运行test() #8 stop_time = time.time() #12 print('运行时间是%s' %(stop_time-start_time)) #13 return wrapper #warpper满足返回值是一个函数名 #5 @timmer #test=timmer(test) #9 def test(): #7 time.sleep(3) #10 print('test函数运行完毕') #11 test() #5