码迷,mamicode.com
首页 > 编程语言 > 详细

python中的无参装饰器和有参装饰器

时间:2018-02-25 00:12:24      阅读:265      评论:0      收藏:0      [点我收藏+]

标签:int   pen   范围   with open   first   代码执行   turn   责任   mysql认证   

                  python中的无参装饰器和有参装饰器

                                       作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。





装饰器特点:

1>.开放封闭原则,即对扩展是开放的,对修改时封闭的;
2>.装饰器本质可以是任意可调用的对象,被装饰的对象也可以是任意可调用对象;
3>.装饰器的功能是在不修改被装饰器对象源代码以及被装饰器对象的调用方式的前提下为其扩展新功能;
4>.装饰器本质是函数,(即装饰其他函数)就是为其他函数添加附加功能。


一.典型装饰器案例
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6 
 7 #装饰器的语法:在被装饰对象的正上方的单独一行,@装饰器名字
 8 import time
 9 import random
10 
11 def RunTime(TheCaller):  #定义装饰器
12     def MyCaller():
13         start_time = time.time()
14         TheCaller()
15         stop_time=time.time()
16         print(run time is %s %(stop_time-start_time))
17     return MyCaller
18 
19 #被装饰函数
20 @RunTime #等效于index=RunTime(index)
21 def index():
22     time.sleep(random.randrange(2,4))   #可以在1-3秒钟(不包括4秒哟)随机睡眠指定范围的时长。
23     print(welecome to INDEX page)
24 
25 @RunTime #home=RunTime(home)
26 def home():
27     time.sleep(random.randrange(1,2))
28     print(welecome to HOME page)
29 
30 index() #MyCaller()
31 home()
32 
33 
34 
35 
36 #以上代码执行结果如下:
37 welecome to INDEX page
38 run time is 2.0000088214874268
39 welecome to HOME page
40 run time is 1.0006351470947266


二.多个装饰器案例展示
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6 
 7 #装饰器的语法:在被装饰对象的正上方的单独一行,@装饰器名字
 8 import time
 9 import random
10 from functools import wraps
11 
12 def RunTime(TheCaller):  #定义装饰器+
13     @wraps(TheCaller)       #可以让用户查看帮助信息的时候查看其自己的源代码定义的帮助信息。
14     def MyCaller(*args,**kwargs):
15         ‘‘‘
16         Runtime‘s help information
17         ‘‘‘
18         start_time = time.time()
19         res = TheCaller(*args,**kwargs)
20         stop_time=time.time()
21         print(run time is %s %(stop_time-start_time))
22         return res
23 
24     return MyCaller
25 
26 def NewAddAuth(TheCaller):
27     def Auth(*args,**kwargs):
28         name=input(username: )
29         password=input(password: )
30         if name == yinzhengjie and password == 123:
31             print(login successful)
32             res = TheCaller(*args,**kwargs)
33             return res
34         else:
35             print(login error)
36     return Auth
37 
38 #被装饰函数
39 # @NewAddAuth
40 @RunTime #等效于index=RunTime(index),装饰器的执行顺序是自下而上。
41 def Index():
42     ‘‘‘
43     Index‘s help information
44     ‘‘‘
45     time.sleep(random.randrange(2,4))   #可以在1-3秒钟(不包括4秒哟)随机睡眠指定范围的时长。
46     print(welecome to INDEX page)
47     return "yinzhengjie"
48 
49 @RunTime #home=RunTime(home)
50 def Home(name):
51     ‘‘‘
52       Home‘s help information
53       ‘‘‘
54     time.sleep(random.randrange(1,2))
55     print(welecome to %s HOME page%(name))
56     return 666
57 
58 res1 = Index() #MyCaller()
59 res2 = Home("尹正杰")
60 print("Index return :%s"%(res1))
61 print("Home return :%s"%(res2))
62 # print(help(Index))
63 # print(Index().__doc__)
64 
65 
66 
67 
68 #以上代码执行结果如下:
69 welecome to INDEX page
70 run time is 3.000018835067749
71 welecome to 尹正杰 HOME page
72 run time is 1.0001890659332275
73 Index return :yinzhengjie
74 Home return :666

 

三.有参装饰器

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6 
 7 ‘‘‘
 8 编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登陆成功一次,后续的函数都无需再验证。
 9 ‘‘‘
10 
11 
12 # user_dic = {
13 #     ‘yinzhengjie‘:‘123‘,
14 #     ‘Golang‘:"666",
15 #     ‘Python‘:"888",
16 # }
17 #
18 # with open("user.db","w",encoding="utf-8")as f:
19 #     f.write(str(user_dic))
20 
21 
22 
23 
24 db_path = "user.db"
25 
26 login_dic ={
27     user:None,
28     "status":False,
29 }
30 
31 def Decorator(AuthType="file"):
32     def auth(func):
33         def wrapper(*args, **kwargs):
34             if AuthType == "file":
35                 if login_dic[user] and login_dic[status]:
36                     res = func(*args, **kwargs)
37                     return res
38                 username = input("username:")
39                 password = input("password:")
40                 with open(db_path, "r", encoding="utf-8")as f:
41                     user_dic = eval(f.read())
42                 if username in user_dic and password == user_dic[username]:
43                     print(login successful)
44                     login_dic[user] = username
45                     login_dic[status] = True
46                     res = func(*args, **kwargs)
47                     return res
48                 else:
49                     print(login error)
50             elif AuthType == "ldap":
51                 print("LDAP认证方式")
52             elif AuthType == "MySQL":
53                 print("MySQL认证方式")
54             else:
55                 print("其他认证方式")
56         return wrapper
57     return auth
58 
59 @Decorator()
60 def Index():
61     print("Welcome to Index!")
62 
63 @Decorator(AuthType="MySQL")
64 def home(name):
65     print("Welecome %s to home page!"%name)
66 
67 Index()
68 home("尹正杰")
69 
70 
71 
72 
73 #以上代码执行结果如下:
74 username:yinzhengjie
75 password:123
76 login successful
77 Welcome to Index!
78 MySQL认证方式

 


四.小试牛刀
1.
编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登陆成功一次,后续的函数都无需再验证。
 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6 
 7 
 8 # user_dic = {
 9 #     ‘yinzhengjie‘:‘123‘,
10 #     ‘Golang‘:"666",
11 #     ‘Python‘:"888",
12 # }
13 #
14 # with open("user.db","w",encoding="utf-8")as f:
15 #     f.write(str(user_dic))
16 
17 
18 
19 
20 db_path = "user.db"
21 
22 login_dic ={
23     user:None,
24     "status":False,
25 }
26 
27 def auth(func):
28     def wrapper(*args,**kwargs):
29         if login_dic[user] and login_dic[status]:
30             res = func(*args, **kwargs)
31             return res
32         username = input("username:")
33         password = input("password:")
34         with open(db_path, "r", encoding="utf-8")as f:
35             user_dic = eval(f.read())
36         if username in user_dic and password == user_dic[username]:
37             print(login successful)
38             login_dic[user] = username
39             login_dic[status] = True
40             res = func(*args,**kwargs)
41             return res
42         else:
43             print(login error)
44     return wrapper
45 
46 @auth
47 def Index():
48     print("Welcome to Index!")
49 
50 @auth
51 def home(name):
52     print("Welecome %s to home page!"%name)
53 
54 Index()
55 home("尹正杰")
56 
57 
58 
59 
60 以上代码执行结果如下:
61 username:yinzhengjie
62 password:123
63 login successful
64 Welcome to Index!
65 Welecome 尹正杰 to home page!

 2.编写下载网页内容的函数,要求功能是:用户传入一个URL,函数返回下载页面的内容。

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 #@author :yinzhengjie
 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
 5 #EMAIL:y1053419035@qq.com
 6 
 7 
 8 from urllib.request import urlopen
 9 import os
10 
11 cache_path=rcache.txt
12 def make_cache(func):
13     def wrapper(*args,**kwargs):
14         if os.path.getsize(cache_path):#说明有缓存
15             print(\033[45m=========有缓存=========\033[0m)
16             with open(cache_path,rb) as f:
17                 res=f.read()
18 
19         else:
20             res=func(*args,**kwargs) #下载
21             with open(cache_path,wb) as f: #制作缓存
22                 f.write(res)
23 
24         return res
25 
26     return wrapper
27 
28 @make_cache
29 def get(url):
30     return urlopen(url).read()
31 
32 
33 print(============first============)
34 print(get(http://www.cnblogs.com/yinzhengjie))
35 print(============second===========)
36 print(get(http://www.cnblogs.com/yinzhengjie))
37 print(============third============)
38 print(get(http://www.cnblogs.com/yinzhengjie))

 





python中的无参装饰器和有参装饰器

标签:int   pen   范围   with open   first   代码执行   turn   责任   mysql认证   

原文地址:https://www.cnblogs.com/yinzhengjie/p/8467930.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!