装饰器:(语法糖)
本质是函数,它是赋予函数新功能,但是不改变函数的源代码及调用方式
原则:
1.不能修改被装饰函数的源代码
2.不能修改被装饰函数的调用方式
3.函数的返回值也不变
这两点简而言之,就是装饰器对被装饰函数来说是透明的
知识储备
1.函数即变量
比如定义了一个变量 x = ‘gkx’ python是一门解释性语言,解释了‘gkx’,并给它分配了内存地址,而 x 就是这个内存地址的一个索引,类似门牌号。
同理可得 def test():print('gkx') 定义了一个函数 test是它的门牌号,print('gkx')分配了一个内存地址。故可以理解为函数即变量。
2.高阶函数
a.把一个函数名当作实参传递给另外一个函数(在不改变函数源代码的情况
为其添加新功能)
b.返回值中包含函数名(不改变函数调用方式
3.嵌套函数
1 嵌套函数 在一个函数的函数体内,用def声明一个新函数 2 def foo(): 3 print('in the foo.') 4 def bar(): 5 print('in the bar.') 6 bar() #要调用bar需要在在函数体内调用,类似局部变量 7 foo()
装饰器例子:仅针对注释的几段,对其进行排序,如下红字
1 import time #python的debug都是先读取最外层框架(最外层没有缩进),最外层中如果涉及到调用,再接着运行调用内容。 第一步 2 3 def timer(func): #当读取到 @timer的时候,相当于运行 test1 = timer(test1),所以会返回来读取 warpper 第三步 4 def warpper(*args,**kwargs): 5 start_time = time.time() 6 func(*args,**kwargs) #此时才是真正意义上运行 test1函数 第六步
return func(*args,**kwargs) #保证fun()返回值也不变 7 stop_time = time.time() 8 print('in the test1() %s'%(stop_time-start_time)) 9 return warpper #把test1当作实参传递给 timer,timer(test1),此时返回的是 函数warpper的内存地址 第四步 10 11 #然后此时运行到 python里的语法【@timer】 12 @timer #相当于 test1 = timer(test1),返回warpper的内存地址,此时如果运行 test1(),相当于 warpper(),warpper就开始执行其函数体内的语句 第二步 13 def test1(): 14 time.sleep(1) 15 print('in the test1')
return ‘from test1’ 16 test1() #此时运行的 test1()已经不是直接运行 test1函数了,是经过@timer,转换成运行 warpper()了 第五步
装饰器进阶版,装饰器本身带参数
1 user = 'gkx' 2 pass_1 = '123' 3 def decorator(auth_type): 4 print("auth type",auth_type) 5 def outer_warpper(func): 6 def warpper(*args,**kwargs): 7 if auth_type == 'local': 8 username = input("id") 9 password = input("password") 10 if username == user and password == pass_1: 11 print('