首页 > 编程语言 > 详细

Python-装饰器

时间:2018-03-25 16:39:28      阅读:186      评论:0      收藏:0      [点我收藏+]

一、什么是装饰器:

  装饰器本身就是函数,功能是为其他函数附加功能。

二、装饰器遵循的原则:

  1、不修改被修饰函数的源代码

  2、不改变被修饰函数的调用方式

三、实现函数装饰器知识储备

  修饰器 = 高阶函数 + 函数嵌套 + 闭包

  示例:有修饰器和没有修饰器的区别:

 1 ## 常规方法实现
 2 import time
 3 
 4 def cal(l):
 5     startTime = time.time()
 6     red = 0
 7     for i in l:
 8         time.sleep(0.1)
 9         red += i
10     stopTime = time.time()
11     print("函数运行时间: %s" %(startTime-stopTime))
12     return red
13 
14 print(cal(range(100)))
15 
16 
17 -------------------------------------------------------------------------
18 ## 使用修饰器实现
19 import time
20 
21 def timer(func):
22     def wrapper(*args,**kwargs):
23         startTime = time.time()
24         red = func(*args,**kwargs)
25         stopTime = time.time()
26         print("函数运行时间:%s" %(startTime-stopTime))
27         return red
28     return wrapper
29 
30 @timer
31 def cal(l):
32     red = 0
33     for i in l:
34         time.sleep(0.1)
35         red += i
36     return red
37 
38 print(cal(range(10)))

 四、高阶函数的定义:(查看 http://www.cnblogs.com/JerryZao/p/8605019.html)

  1、函数接受的参数是一个函数名

  2、函数返回的是一个函数名

  以上满足一个即可称为高阶函数

五、函数嵌套

  1、什么是函数嵌套

    函数嵌套是在函数的内部重新定义一个新的函数,而不是调用一个函数

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(xxxx)

 

六、闭包

 1 ‘‘‘
 2 闭包:在一个作用域里放入定义变量,相当于打了一个包
 3 ‘‘‘
 4 def father(name):
 5     def son():
 6         # name=‘alex‘
 7         print(我爸爸是 [%s] %name)
 8         def grandson():
 9             # name=‘wupeiqi‘
10             print(我爷爷是 [%s] %name)
11         grandson()
12     son()
13 
14 father(xxxx)
 1 ## 再举个例子
 2 def line_conf(a, b):
 3     def line(x):
 4         return b*x + a
 5 
 6     return line
 7 
 8 line_conf(1,2)
 9 
10 # 我们可以看到,只要环境变量a,b 的值定了,那么line函数的表达式也就定了,只取决于自己的函数参数

 

七、无参数修饰器

  无参修饰器 = 高阶函数 + 函数嵌套

  1、基本框架

1 #这就是一个实现一个装饰器最基本的架子
2 def timer(func):
3     def wrapper():
4         func()
5 
6     return wrapper

 

  2、加上参数

1 def timer(func):
2     def wrapper(*args,**kwargs):
3         func(*args,**kwargs)
4     return wrapper

  3、加上功能

1 import time
2 def timer(func):
3     def wrapper(*args,**kwargs):
4         start_time=time.time()
5         func(*args,**kwargs)
6         stop_time=time.time()
7         print(函数[%s],运行时间是[%s] %(func,stop_time-start_time))
8     return wrapper

 

  4、加上返回值

1 import time
2 def timer(func):
3     def wrapper(*args,**kwargs):
4         start_time=time.time()
5         res=func(*args,**kwargs)
6         stop_time=time.time()
7         print(函数[%s],运行时间是[%s] %(func,stop_time-start_time))
8         return res
9     return wrapper

 

  5、使用装饰器

1 def cal(array):
2     res=0
3     for i in array:
4         res+=i
5     return res
6 
7 cal=timer(cal)
8 cal(range(10))

 

  6、语法糖 @

1 @timer  #@timer就等同于cal=timer(cal)   cal就是wrapper  ,cal()就是执行wrapper()函数
2 def cal(array):
3     res=0
4     for i in array:
5         res+=i
6     return res
7 
8 cal(range(10))

 

  分析示例 

 1 import time
 2 def timmer(func): #func=test1
 3     def wrapper(*args,**kwargs): #test(‘linhaifeng‘,age=18)  args=(‘linhaifeng‘)  kwargs={‘age‘:18} 将参数完整的传给func
 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)

 

八、装饰器应用案例:

  写一个模拟JD网站,用户认证登录网站和购物加入购物车功能程序

  实现功能:用装饰器给所有的函数加上验证功能

  示例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 user_list=[
 2     {name:alex,passwd:123},
 3     {name:linhaifeng,passwd:123},
 4     {name:wupeiqi,passwd:123},
 5     {name:yuanhao,passwd:123},
 6 ]
 7 
 8 current_user={username:None,login:False}
 9 
10 def auth_deco(func):
11     def wrapper(*args,**kwargs):
12         if current_user[username] and current_user[login]:
13             res=func(*args,**kwargs)
14             return res
15         username=input(用户名: ).strip()
16         passwd=input(密码: ).strip()
17 
18         for index,user_dic in enumerate(user_list):
19             if username == user_dic[name] and passwd == user_dic[passwd]:
20                 current_user[username]=username
21 
22                 current_user[login]=True
23                 res=func(*args,**kwargs)
24                 return res
25                 break
26         else:
27             print(用户名或者密码错误,重新登录)
28 
29     return wrapper
30 
31 @auth_deco
32 def index():
33     print(欢迎来到主页面)
34 
35 @auth_deco
36 def home():
37     print(这里是你家)
38 
39 def shopping_car():
40     print(查看购物车啊亲)
41 
42 def order():
43     print(查看订单啊亲)
44 
45 print(user_list)
46 # index()
47 print(user_list)
48 home()
49 
50 无参装饰器
无参数(语法糖)
技术分享图片
 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 
 8 current_user={username:None,login:False}
 9 def auth(auth_type=file):
10     def auth_deco(func):
11         def wrapper(*args,**kwargs):
12             if auth_type == file:
13                 if current_user[username] and current_user[login]:
14                     res=func(*args,**kwargs)
15                     return res
16                 username=input(用户名: ).strip()
17                 passwd=input(密码: ).strip()
18 
19                 for index,user_dic in enumerate(user_list):
20                     if username == user_dic[name] and passwd == user_dic[passwd]:
21                         current_user[username]=username
22                         current_user[login]=True
23                         res=func(*args,**kwargs)
24                         return res
25                         break
26                 else:
27                     print(用户名或者密码错误,重新登录)
28             elif auth_type == ldap:
29                 print(巴拉巴拉小魔仙)
30                 res=func(*args,**kwargs)
31                 return res
32         return wrapper
33     return auth_deco
34 
35 
36 #auth(auth_type=‘file‘)就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type=‘file‘)
37 #就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type=‘file‘参数
38 @auth(auth_type=ldap)
39 def index():
40     print(欢迎来到主页面)
41 
42 @auth(auth_type=ldap)
43 def home():
44     print(这里是你家)
45 
46 def shopping_car():
47     print(查看购物车啊亲)
48 
49 def order():
50     print(查看订单啊亲)
51 
52 # print(user_list)
53 index()
54 # print(user_list)
55 home()
56 
57 带参装饰器
含有参数

 

九、补充:

  解压序列

 1 a,b,c = [1,2,3]
 2 
 3 --->
 4 
 5 a=1
 6 b=2
 7 c=3
 8 
 9 
10 s = [1,2,3,5,6,7,8,8,9,0,0,32,453,5435,23,5,675,6]
11 a,*_,b = s
12 print(a) # 1
13 print(b) # 6

  值交换

1 a = 1
2 b = 2
3 
4 ----->
5 
6 a,b = b,a
7 
8 # 这样就ab的值交换了

 

 

  

Python-装饰器

原文:https://www.cnblogs.com/JerryZao/p/8645266.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!