博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python中的无参装饰器和有参装饰器
阅读量:6202 次
发布时间:2019-06-21

本文共 9057 字,大约阅读时间需要 30 分钟。

                  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 random10 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 MyCaller18 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 page38 run time is 2.000008821487426839 welecome to HOME page40 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 random10 from functools import wraps11 12 def RunTime(TheCaller):  #定义装饰器+13     @wraps(TheCaller)       #可以让用户查看帮助信息的时候查看其自己的源代码定义的帮助信息。14     def MyCaller(*args,**kwargs):15         '''16         Runtime's help information17         '''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 res23 24     return MyCaller25 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 res34         else:35             print('login error')36     return Auth37 38 #被装饰函数39 # @NewAddAuth40 @RunTime #等效于index=RunTime(index),装饰器的执行顺序是自下而上。41 def Index():42     '''43     Index's help information44     '''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 information53       '''54     time.sleep(random.randrange(1,2))55     print('welecome to %s HOME page'%(name))56     return 66657 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 page70 run time is 3.00001883506774971 welecome to 尹正杰 HOME page72 run time is 1.000189065933227573 Index return :yinzhengjie74 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 res38 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'] = username45 login_dic['status'] = True46 res = func(*args, **kwargs)47 return res48 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 wrapper57 return auth58 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:yinzhengjie75 password:12376 login successful77 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 res32 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'] = username39 login_dic['status'] = True40 res = func(*args,**kwargs)41 return res42 else:43 print('login error')44 return wrapper45 46 @auth47 def Index():48 print("Welcome to Index!")49 50 @auth51 def home(name):52 print("Welecome %s to home page!"%name)53 54 Index()55 home("尹正杰")56 57 58 59 60 以上代码执行结果如下:61 username:yinzhengjie62 password:12363 login successful64 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 os10 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 res25 26     return wrapper27 28 @make_cache29 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]=func12         # def wrapper(*args,**kwargs):          #此行及以下3行可以不写,这样就可以达到隐藏你原来函数的名字。13         #     res = func(*args,**kwargs)14         #     return res15         # return wrapper16     return deco17 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':
, 'two':
, 'three':
}43 >>>:three44 From Third45 >>>:one46 From Shell47 >>>:two48 From Second49 >>>:50 >>>:51 >>>:
 

转载于:https://www.cnblogs.com/yinzhengjie/p/8467930.html

你可能感兴趣的文章
每日一练,Python爬取主要城市螺纹钢价格总汇
查看>>
python机器人:基于图灵的API开发,只需20行代码
查看>>
使用eclipse编译含有C++11特性的代码
查看>>
OSChina 周三乱弹 —— 国家命运与个人命运
查看>>
研究一下Android中的动画效果
查看>>
column reference "c_bh" is ambiguous
查看>>
oracle 常用分析聚合函数
查看>>
android 将图片的四角圆化 与 剪裁圆形图片
查看>>
Linux下Tomcat重新启动
查看>>
打印某年日历
查看>>
UITextView设置超链接,点击跳转到应用内的webView
查看>>
150127随手记
查看>>
页面里面设置简单的图形
查看>>
django 学习笔记(四)
查看>>
freemarker IDE 安装
查看>>
DOUBLE vs DECIMAL 区别
查看>>
Linux目录结构和常用命令
查看>>
TCP协议的三次握手和四次挥手
查看>>
C# 7.0
查看>>
安卓手机游戏 纪念碑谷1+2+被遗忘海岸+艾达的梦 解锁码
查看>>