一:什么叫装饰器
1.装饰器:本质就是函数,为其他函数添加附加功能
(原则:不修改被修饰函数的源代码,不修改被修饰函数的调用方法)
1 import time 2 def cal(l): 3 start_time=time.time() 4 res=0 5 for i in l: 6 res+=i 7 stop_time=time.time() 8 print('函数的运行时间是%s' %(stop_time-start_time)) 9 return res 10 print(cal(range(100))) 11 #结果:函数的运行时间是0.0 12 # 4950
2.装饰器=高阶函数+函数嵌套+闭包
【1】高阶函数定义:
1 1.函数接收的参数是一个函数名 2 2.函数的返回值是一个函数名 3 3.满足上述条件任意一个,都可称之为高阶函数
1 #函数接收的参数是函数名 2 import time 3 def foo(): 4 print('nihao') 5 def test(func): 6 # print(func) 7 start_time=time.time() 8 func() 9 stop_time=time.time() 10 print('函数的运行时间是 %s' %(stop_time-start_time)) 11 test(foo) #接收的参数是一个函数名foo 12 #结果:nihao 13 # 函数的运行时间是 0.0
1 #函数的返回值是函数名 2 def foo(): 3 print('from the foo') 4 def test(func): 5 return func 6 res=test(foo) 7 print(res) #res的内存地址 8 res() #res加括号直接运行出来 9 #结果:<function foo at 0x0000013458554950> 10 # from the foo
【2】函数闭包(嵌套):
1 #函数闭包,一层套一层,关闭的一层套一层,把变量闭包到里面 2 def father(name): 3 def son(): 4 name='zy' 5 print('爸爸是%s' %name) 6 son() 7 father('zy') #永远往上层找 8 #结果:爸爸是zy
#函数闭包补充:解压序列
1 >>>list=[1,2,3,8,9,6] 2 >>>a.*_.c=list 3 >>>a 4 1 5 >>>c 6 6 7 #取列表的第一个与最后一个元素 8 >>>f1=1 9 >>>f2=2 10 >>>f1,f2=f2,f1 11 #直接交换f1,f2的值
3.装饰器基本实现
1 #装饰器的框架 2 def timmer(func): 3 def wrapper(): 4 print(func) 5 func() 6 return wrapper 7 例子: 8 import time 9 #装饰器的框架 10 def timmer(func): 11 def wrapper(): 12 #print(func) 13 start_time=time.time() 14 func() #就是在运行test() 15 stop_time=time.time() 16 print('运行时间是%s' %(stop_time-start_time)) 17 return wrapper 18 19 def test(): 20 time.sleep(3) 21 print('test函数运行完毕') 22 23 res=timmer(test) #返回的是wrapper的地址 24 res() #执行的是wrapper() 25 #结果:test函数运行完毕 26 # 运行时间是3.01176118850708 27 28 res=timmer(test) #返回的是wrapper的地址 29 res() #执行的是wrapper() 30 #上面这块可以修改成: 31 test=timmer(test) 32 test() 33 还可以使用语法糖#@timmer(python提供的)替代赋值,在def test():上面加@timmer装饰器名字就可以
#函数闭包加参数:
1 import time 2 #装饰器的框架 3 def timmer(func): 4 def wrapper(name,age): 5 #print(func) 6 start_time=time.time() 7 res=func(name,age) #就是在运行test() 8 stop_time=time.time() 9 print('运行时间是%s' %(stop_time-start_time)) 10 return res 11 return wrapper 12 13 @timmer #test=timmer(test) 14 def test(name,age): 15 time.sleep(3) 16 print('test函数运行完毕,名字是【%s】 年龄是【%s】' %(name,age)) 17 return '这是test的返回值' 18 19 # res=timmer(test) #返回的是wrapper的地址 20 res=test('zy',18) #执行的是wrapper() 21 print(res) 22 #结果:test函数运行完毕,名字是【zy】 年龄是【18】 23 # 运行时间是3.0002963542938232 24 # 这是test的返回值
#函数闭包为函数加上认证功能:
1 def auth_func(func): 2 def wrapper(*args,**kwargs): 3 username=input('用户名:').strip() 4 passwd= input('密码:').strip() 5 if username=='周圆' and passwd=='123': 6 res=func(*args,**kwargs) 7 return res 8 else: 9 print('用户名或密码错误!') 10 return wrapper 11 @auth_func 12 def index(): 13 print('欢迎来到京东主页') 14 @auth_func 15 def home(name): 16 print('欢迎回家%s' %name) 17 @auth_func 18 def shopping_car(name): 19 print('%s的购物车里有[%s]' %(name,'奶茶')) 20 21 index() 22 home('周圆') 23 shopping_car('周圆') 24 #结果:用户名:周圆 25 # 密码:123 26 # 欢迎来到京东主页 27 # 用户名:周圆 28 # 密码:1234 29 # 用户名或密码错误! 30 # 用户名:周圆 31 # 密码:123 32 # 周圆的购物车里有[奶茶]
#函数闭包模拟session:
user_dic={'username':None,'login':False} def auth_func(func): def wrapper(*args,**kwargs): if user_dic['username'] and user_dic['login']: res = func(*args, **kwargs) return res username=input('用户名:').strip() passwd= input('密码:').strip() if username=='周圆' and passwd=='123': user_dic['username']=username user_dic['login']=True res=func(*args,**kwargs) return res else: print('用户名或密码错误!') return wrapper @auth_func def index(): print('欢迎来到京东主页') @auth_func def home(name): print('欢迎回家%s' %name) @auth_func def shopping_car(name): print('%s的购物车里有[%s]' %(name,'奶茶')) index() home('周圆') shopping_car('周圆') #用户名:周圆 #密码:123 #欢迎来到京东主页 #欢迎回家周圆 #周圆的购物车里有[奶茶]