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

                  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=r'cache.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'))

 3.装饰器包装原函数案例

 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 FuncDict={}
 8 
 9 def MakeDict(key):
10     def deco(func):
11         FuncDict[key]=func
12         # def wrapper(*args,**kwargs):          #此行及以下3行可以不写,这样就可以达到隐藏你原来函数的名字。
13         #     res = func(*args,**kwargs)
14         #     return res
15         # return wrapper
16     return deco
17 
18 
19 @MakeDict("one")
20 def First():
21     print("From Shell")
22 
23 
24 @MakeDict("two")
25 def Second():
26     print("From Second")
27 
28 @MakeDict("three")
29 def Third():
30     print("From Third")
31 
32 print(FuncDict)
33 
34 while True:
35     cmd = input(">>>:").strip()
36     if  cmd in FuncDict:
37         FuncDict[cmd]()
38 
39 
40 
41 #以上代码执行结果如下:
42 {'one': <function First at 0x027E38E8>, 'two': <function Second at 0x027E3810>, 'three': <function Third at 0x027E38A0>}
43 >>>:three
44 From Third
45 >>>:one
46 From Shell
47 >>>:two
48 From Second
49 >>>:
50 >>>:
51 >>>:
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值