实现装饰器需要具备那些知识:
1.函数既”变量” 属于可变化数据
函数是无关顺序的,但是执行调用的函数必须在执行代码前面
示例:
变量:
a=[1,2] #a为变量名,[1,2]存放内存里面 ==专业称之变量体
函数:
def test1():
.....
#test1==该函数的名字(如变量名a)
#():内的代码 == [1,2]存放在内存里面 ==专业称之函数体
#注意1:test1获取该函数的内存地址 、test1+ ()==执行该test1函数
#注意2:变量体(函数体)必须最少拥有一个变量名(函数名),否则内存回收
2.高阶函数
a:把一个函数名当做实参传给另外一个函数的函数:
通过实验得到:在不修改被装饰函数源代码的情况下为其添加了功能
b:返回值中包含函数名
通过实验得到:不修改函数的调用方式和源代码也可以添加功能
示例:
import time
def bar():
time.sleep(3)
print('in the bar')
def test2(func):
print(func)
return func
test2(bar)()
#bar获取的是函数bar函数的内存地址
#bar()才是执行该函数
3.嵌套函数
高阶函数+嵌套函数=装饰器
示例:
import time
def timmer(func):
def warpper(*args,**kwargs):
start_time = time.time()#开始时间
func()#调用开始时间(该装饰我还不清楚,目前这样解释)
stop_time = time.time()#结束时间
print('the func run time is %s' %(stop_time-start_time))#打印显示xxx开始时间-
return warpper
def test():
time.sleep(3)#间隔3秒,也就是被调用了执行到该步骤的时候停3秒,继续往下操作
print('in the test')
a=timmer(test) # a == warpper
a() # a()==warpper()
#timmer(test)() == warpper()等于上面两条命令
详解:
- timmer(test1)得到的是warpper的该函数内存地址
- timmer(func) func=test该函数体
- 赋值a a() ==warpper()
- 全局变量和局部变量规则,意味着warpper()可以调用timmer函数的形参func
- 最终执行了func() == test()
timmer函数符合高阶函数,和嵌套函数,所以是装饰器
经过Python优化以后装饰器调用变成如下:
@timmer装饰到指定的函数如def test1()上面:
import time
def timmer(func):
def warpper(*args,**kwargs):
start_time = time.time()#开始时间
func()#调用开始时间(该装饰我还不清楚,目前这样解释)
stop_time = time.time()#结束时间
print('the func run time is %s' %(stop_time-start_time))#打印显示xxx开始时间-
return warpper
@timmer#调用装饰器,在需要装饰的函数的上方
def test():
time.sleep(3)#间隔3秒,也就是被调用了执行到该步骤的时候停3秒,继续往下操作
print('in the test')
test()
#带装饰器和正常写法的转换:
#func = test
#test = timmer(test) == warpper
#test()=timmer(test)() == warpper()
test该函数有形参怎么办?
1.我们知道func = test
2.timmer(test1)得到的是warpper的该函数内存地址赋值到test
3.test() == warpper()
4. warpper函数增加参数组(元祖和字典)
5. test(1,2) == warpper(1,2) warpper函数执行func的时候在把形参给func就OK了fun(1,2)
示例:
import time
def timmer(func):
def warpper(*args,**kwargs):
start_time = time.time()#开始时间
func(args[0], args[1])#调用开始时间(该装饰我还不清楚,目前这样解释)
stop_time = time.time()#结束时间
print('the func run time is %s' %(stop_time-start_time))#打印显示xxx开始时间-
return warpper
@timmer#调用装饰器,在需要装饰的函数的上方
def test(a,b):
time.sleep(3)#间隔3秒,也就是被调用了执行到该步骤的时候停3秒,继续往下操作
print('in the test')
test(1,2)
#带装饰器和正常写法的转换:
#func = test
#test = timmer(test) == warpper
#test1(1,2)=timmer(test)(1,2) == warpper(1,2)
# func(args[0], args[1]) == test(1,2)
test该函数有return怎么办?
示例:
import time
def timmer(func):
def warpper(*args,**kwargs):
start_time = time.time()#开始时间
res = func(args[0], args[1])#调用开始时间(该装饰我还不清楚,目前这样解释)
stop_time = time.time()#结束时间
print('the func run time is %s' %(stop_time-start_time))#打印显示xxx开始时间-
return res
return warpper
@timmer#调用装饰器,在需要装饰的函数的上方
def test(a,b):
time.sleep(3)#间隔3秒,也就是被调用了执行到该步骤的时候停3秒,继续往下操作
return 1
res = test(1,2)
高阶装饰器(其实都是一样)