标签:结果 改变 框架 -- ping 购物 作用域 运行时间 from
一、什么是装饰器
装饰器本质就是函数,功能是为其他函数附加功能
二、装饰器遵循的原则
1、不修改被修饰函数的源代码
2、不修改被修饰函数的调用方式
三、实现装饰器的知识储备
装饰器=高阶函数+函数嵌套+闭包
示例1: 用函数实现
1 #计算从1-100,统计函数运行时间 2 3 import time 4 def cal(l): 5 start_time=time.time() 6 res=0 7 for i in l: 8 time.sleep(0.1) 9 res+=i 10 stop_time = time.time() 11 print(‘函数的运行时间是%s‘ %(stop_time-start_time)) 12 return res 13 14 print(cal(range(100))) #直接打印得到运行的时间
执行结果:
1 函数的运行时间是10.007169723510742 2 4950
示例2:用装饰器实现函数运行时间
1 import time 2 def timmer(func): 3 def wrapper(*args,**kwargs): 4 start_time=time.time() 5 res=func(*args,**kwargs) 6 stop_time = time.time() 7 print(‘函数运行时间是%s‘ %(stop_time-start_time)) 8 return res 9 return wrapper 10 11 @timmer #调用装饰器 12 def cal(l): 13 res=0 14 for i in l: 15 time.sleep(0.1) 16 res+=i 17 return res 18 19 res=cal(range(20)) 20 print(res)
四、高阶函数高阶函数定义
1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名
3.满足上述条件任意一个,都可称之为高阶函数
高阶函数示例如下:
示例1:函数接收的参数是一个函数名
1 #1.函数接收的参数是一个函数名 2 import time 3 def foo(): 4 time.sleep(3) 5 print(‘你好啊林师傅‘) 6 7 def test(func): #test高阶函数 8 # print(func) #获取到内存地址 9 start_time=time.time() 10 func() 11 stop_time = time.time() 12 print(‘函数运行时间是 %s‘ % (stop_time-start_time)) 13 # foo() 14 test(foo)
执行结果:
1 你好啊林师傅 2 函数运行时间是 3.0003013610839844 3 来自foo
示例2:
1 def foo(): 2 print(‘from the foo‘) 3 def test(func): 4 return func 5 6 # res=test(foo) 7 # # print(res) 8 # res() 9 10 foo=test(foo) 11 # # print(res) 12 foo() 13 14 import time 15 def foo(): 16 time.sleep(3) 17 print(‘来自foo‘) 18 19 #不修改foo源代码 20 #不修改foo调用方式
示例3:
1 #多运行了一次,不合格 2 import time 3 def foo(): 4 time.sleep(3) 5 print(‘来自foo‘) 6 7 def timer(func): 8 start_time=time.time() 9 func() 10 stop_time = time.time() 11 print(‘函数运行时间是 %s‘ % (stop_time-start_time)) 12 return func 13 foo=timer(foo) 14 foo()
示例4:
1 #没有修改被修饰函数的源代码,也没有修改被修饰函数的调用方式,但是也没有为被修饰函数添加新功能 2 import time 3 def foo(): 4 time.sleep(3) 5 print(‘来自foo‘) 6 7 def timer(func): 8 start_time=time.time() 9 return func 10 stop_time = time.time() 11 print(‘函数运行时间是 %s‘ % (stop_time-start_time)) 12 13 foo=timer(foo) 14 foo()
执行结果:
1 来自foo
结论:高阶函数,满足不了装饰器的功能。
高阶函数总结:
1.函数接收的参数是一个函数名
作用:在不修改函数源代码的前提下,为函数添加新功能,
不足:会改变函数的调用方式
2.函数的返回值是一个函数名
作用:不修改函数的调用方式
不足:不能添加新功能
五、函数的嵌套
1、什么是函数的嵌套?
通过在函数内部def的关键字再声明一个函数即为嵌套
示例:
1 def father(name): 2 def son(): 3 print(‘我的爸爸是%s‘ %name) 4 def grandson(): 5 name=‘就是我自己‘ 6 print(‘我的爷爷是%s‘ %name) 7 grandson() 8 son() 9 father(‘linhaifeng‘)
执行结果:
1 我的爸爸是linhaifeng 2 3 我的爷爷是就是我自己
六、闭包
1 #闭包:在一个作用域里放入定义变量,相当于打了一个包 2 def father(auth_type): 3 # print(‘from father %s‘ %name) 4 def son(): 5 # name=‘linhaifeng_1‘ 6 # print(‘我的爸爸是%s‘ %name) 7 def grandson(): 8 print(‘我的爷爷是%s‘ %auth_type) 9 grandson() 10 # print(locals()) 11 son() 12 # father(‘linhaifeng‘) 13 father(‘filedb‘)
执行结果:
1 我的爷爷是filedb
七、无参装饰器
无参装饰器=高级函数+函数嵌套
1、基本框架
1 #这就是一个实现一个装饰器最基本的架子 2 def timer(func): 3 def wrapper(): 4 func() 5 6 return wrapper
2、基本装饰器(基本框架+参数+功能+返回值+使用装饰器+语法糖@)
import time
def timmer(func): #func=test
def wrapper():
# print(func)
start_time=time.time()
func() #就是在运行test()
stop_time = time.time()
print(‘运行时间是%s‘ %(stop_time-start_time))
return wrapper
@timmer #test=timmer(test) #在函数名前面加个@ ,这就是语法糖
def test():
time.sleep(3)
print(‘test函数运行完毕‘)
test()
代码说明:
1 # res=timmer(test) #返回的是wrapper的地址 2 # res() #执行的是wrapper() 3 # 4 # test=timmer(test) #返回的是wrapper的地址 5 # test() #执行的是wrapper() 6 # 7 # @timmer 就相当于 test=timmer(test)
执行结果:
1 test函数运行完毕 2 运行时间是3.000155210494995
3、加上返回值
1 import time 2 def timmer(func): #func=test 3 def wrapper(): 4 start_time=time.time() 5 res=func() #就是在运行test() 6 stop_time = time.time() 7 print(‘运行时间是%s‘ %(stop_time-start_time)) 8 return res 9 return wrapper 10 11 @timmer #test=timmer(test) 12 def test(): 13 time.sleep(3) 14 print(‘test函数运行完毕‘) 15 return ‘这是test的返回值‘ 16 17 res=test() #就是在运行wrapper 18 print(res)
执行结果:
1 test函数运行完毕 2 运行时间是3.0001416206359863 3 这是test的返回值
4、加上参数
1 import time
2 def timmer(func): #func=test1
3 def wrapper(*args,**kwargs): #test(‘linhaifeng‘,age=18) args=(‘linhaifeng‘) kwargs={‘age‘:18}
4 start_time=time.time()
5 res=func(*args,**kwargs) #就是在运行test() func(*(‘linhaifeng‘),**{‘age‘:18})
6 stop_time = time.time()
7 print(‘运行时间是%s‘ %(stop_time-start_time))
8 return res
9 return wrapper
10
11 # @timmer #test=timmer(test)
12 def test(name,age):
13 time.sleep(3)
14 print(‘test函数运行完毕,名字是【%s】 年龄是【%s】‘ %(name,age))
15 return ‘这是test的返回值‘
16
17 @timmer
18 def test1(name,age,gender):
19 time.sleep(1)
20 print(‘test1函数运行完毕,名字是【%s】 年龄是【%s】 性别【%s】‘ %(name,age,gender))
21 return ‘这是test的返回值‘
22
23 # res=test(‘linhaifeng‘,age=18) #就是在运行wrapper
24 # # print(res)
25 # test1(‘alex‘,18,‘male‘)
26
27 test1(‘alex‘,18,‘male‘)
执行结果:
1 test1函数运行完毕,名字是【alex】 年龄是【18】 性别【male】 2 运行时间是1.0007386207580566
八、装饰器应用案例
写一个模拟京东网站,用户认证登录网站和购物加入购物车功能程序
实现功能:用装饰器给所有函数加上验证功能
1、基本框架
1 def index(): 2 pass 3 4 def home(): 5 pass 6 7 def shopping_car() 8 pass 9 10 def order() 11 pass
2、开始实现
示例1:没有判断验证方式,直接就显示购物车结果。
1 user_list=[
2 {‘name‘:‘alex‘,‘passwd‘:‘123‘},
3 {‘name‘:‘linhaifeng‘,‘passwd‘:‘123‘},
4 {‘name‘:‘wupeiqi‘,‘passwd‘:‘123‘},
5 {‘name‘:‘yuanhao‘,‘passwd‘:‘123‘},
6 ]
7 current_dic={‘username‘:None,‘login‘:False}
8
9 def auth(auth_type=‘filedb‘):
10 def auth_func(func):
11 def wrapper(*args,**kwargs):
12 print(‘认证类型是‘,auth_type)
13 if auth_type == ‘filedb‘:
14 if current_dic[‘username‘] and current_dic[‘login‘]:
15 res = func(*args, **kwargs)
16 return res
17 username=input(‘用户名:‘).strip()
18 passwd=input(‘密码:‘).strip()
19 for user_dic in user_list:
20 if username == user_dic[‘name‘] and passwd == user_dic[‘passwd‘]:
21 current_dic[‘username‘]=username
22 current_dic[‘login‘]=True
23 res = func(*args, **kwargs)
24 return res
25 else:
26 print(‘用户名或者密码错误‘)
27 elif auth_type == ‘ldap‘:
28 print(‘鬼才特么会玩‘)
29 res = func(*args, **kwargs)
30 return res
31 else:
32 print(‘鬼才知道你用的什么认证方式‘)
33 res = func(*args, **kwargs)
34 return res
35
36 return wrapper
37 return auth_func
38
39 @auth(auth_type=‘filedb‘) #auth_func=auth(auth_type=‘filedb‘)-->@auth_func 附加了一个auth_type --->index=auth_func(index)
40 def index():
41 print(‘欢迎来到京东主页‘)
42
43 @auth(auth_type=‘ldap‘)
44 def home(name):
45 print(‘欢迎回家%s‘ %name)
46 #
47 @auth(auth_type=‘sssssss‘)
48 def shopping_car(name):
49 print(‘%s的购物车里有[%s,%s,%s]‘ %(name,‘奶茶‘,‘妹妹‘,‘娃娃‘))
50
51 # print(‘before-->‘,current_dic)
52 # index()
53 # print(‘after--->‘,current_dic)
54 # home(‘产品经理‘)
55 shopping_car(‘产品经理‘)
执行结果:
1 认证类型是 sssssss 2 鬼才知道你用的什么认证方式 3 产品经理的购物车里有[奶茶,妹妹,娃娃]
示例2 :给他加上验证功能装饰器(判断用户和密码,跟字典里的用户和密码进行比对)
1 user_list=[
2 {‘name‘:‘alex‘,‘passwd‘:‘123‘},
3 {‘name‘:‘linhaifeng‘,‘passwd‘:‘123‘},
4 {‘name‘:‘wupeiqi‘,‘passwd‘:‘123‘},
5 {‘name‘:‘yuanhao‘,‘passwd‘:‘123‘},
6 ]
7 current_dic={‘username‘:None,‘login‘:False}
8
9
10 def auth_func(func):
11 def wrapper(*args,**kwargs):
12 if current_dic[‘username‘] and current_dic[‘login‘]:
13 res = func(*args, **kwargs)
14 return res
15 username=input(‘用户名:‘).strip()
16 passwd=input(‘密码:‘).strip()
17 for user_dic in user_list:
18 if username == user_dic[‘name‘] and passwd == user_dic[‘passwd‘]:
19 current_dic[‘username‘]=username
20 current_dic[‘login‘]=True
21 res = func(*args, **kwargs)
22 return res #返回值
23 else:
24 print(‘用户名或者密码错误‘)
25
26 return wrapper
27
28 @auth_func #加证功能,也是装饰器
29 def index():
30 print(‘欢迎来到京东主页‘)
31
32 @auth_func
33 def home(name):
34 print(‘欢迎回家%s‘ %name)
35
36 @auth_func
37 def shopping_car(name):
38 print(‘%s的购物车里有[%s,%s,%s]‘ %(name,‘奶茶‘,‘妹妹‘,‘娃娃‘))
39
40 print(‘before-->‘,current_dic)
41 index()
42 print(‘after--->‘,current_dic)
43 home(‘产品经理‘)
44 shopping_car(‘产品经理‘)
执行结果:
1 before--> {‘username‘: None, ‘login‘: False}
2 用户名:alex #输入字典里的用户名和密码,才能登录成功。
3 密码:123
4 欢迎来到京东主页
5 after---> {‘username‘: ‘alex‘, ‘login‘: True}
6 欢迎回家产品经理
7 产品经理的购物车里有[奶茶,妹妹,娃娃]
标签:结果 改变 框架 -- ping 购物 作用域 运行时间 from
原文地址:https://www.cnblogs.com/trunkslisa/p/9212611.html