一、装饰器(decorator)
1.定义:本质是函数(装饰其它函数),就是为了其它函数添加附加功能。
2.原则:一是不能修改被装饰函数的源代码;二是不能修改被装饰函数的调用方式。
3.装饰器包含的知识点:
<1>函数(可作为变量)
<2>高阶函数
a.把一个函数名当作实参传给另一个函数(在不修改被装饰函数的情况下,为其添加新功能)
b.返回值中包含函数名(不修改函数的调用方式)
<3>嵌套函数
高阶函数 + 嵌套函数 ==》 装饰器
4.下面举例分析:
<1>把一个函数名当作实参传给另一个函数
1 import time 2 #把一个函数名当作实参传给另一个函数 3 def hyt(): 4 time.sleep(3) #延迟三秒 5 print('This is hyt') 6 7 def congcong(func): #函数作为变量 8 str_time = time.time() #记录开始时间 9 func() #运行hyt函数 10 stop_time = time.time() #记录结束时间 11 print('The func runs time is %s '%(stop_time-str_time)) #输出:The func runs time is 3.000171661376953 12 13 congcong(hyt)
<2>返回值中包含函数名
import time #返回值中包含函数名(不修改函数的调用方式) def hyt(): time.sleep(3) #延迟三秒 print('This is hyt') def cc(func): print(func)#打印hyt函数的内存地址,结果:<function hyt at 0x00206780> return func #返回hyt函数的内存地址 hyt=cc(hyt) #cc(hyt)表示传递hyt函数的内存地址,而cc(hyt())表示传递hyt函数的返回值,不符合高阶函数的定义 hyt() #运行hyt函数
<3>嵌套函数
1 def foo(): 2 # '嵌套函数:在一个函数的函数体内部用def声明并调用另一个函数。' 3 print('This is foo') 4 def func(): #局部起作用,故只能在函数体内部调用 5 print('This is func') 6 7 func() 8 foo()
<4>#局部作用域与全局作用域的访问顺序
5.装饰器实际运用
<1>简单点的:
1 def timer(func): #timer(cc1) func = cc1 2 'decorator(装饰器高潮版)' 3 def hyt(*args,**kwargs): #非固定传参,前者接受位置参数,后者接受关键字参数 4 star_time = time.time() #time.time()调用时间的计时功能 5 func(*args,**kwargs) #run cc1() 6 stop_time = time.time() 7 print('The func running time is %s'%(stop_time-star_time)) 8 return hyt 9 @timer #等同于cc1 = timer(cc1) 10 def cc1(): 11 time.sleep(1) 12 print('This is cc1..') 13 cc1() 14 15 @timer #等同于cc2 = timer(cc2) = hyt cc2()=>hyt() ==> cc2(name,age)==>hyt(name.age) 16 def cc2(name,age): 17 time.sleep(3) 18 print('Name is 33[32;1m{s1} 33[0m,Age is 33[31;1m{s2} 33[0m'.format(s1=name,s2=age)) 19 cc2('SC',20)
<2>复杂点的:
1 #装饰器经典款 2 import time 3 user = 'cc' 4 passwd = '123456' 5 def auth(func): 6 def wrapper(*args,**kwargs): 7 usename = input('Usename:').strip() 8 password = input('Password:').strip() 9 if user == usename and passwd == password: 10 print('Welcome 33[32;1m%s hased passed authentication 33[0m'%(usename)) 11 func(*args,**kwargs) 12 else: 13 exit('