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 >>>:
转载于:https://www.cnblogs.com/yinzhengjie/p/8467930.html
python中的无参装饰器和有参装饰器相关推荐
- python作用域的理解-python中对变量的作用域LEGB、闭包、装饰器基本理解
一.作用域 在Python程序中创建.改变.查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域.python的作用域是静态的,在源代码中变量名被赋值的位置决定了该变量 ...
- 在Python中的无参装饰器和有参装饰器
装饰器特点: 1.开放封闭原则,即对扩展是开放的,对修改时封闭的: 2.装饰器本质可以是任意可调用的对象,被装饰的对象也可以是任意可调用对象: 3.装饰器的功能是在不修改被装饰器对象源代码以及被装饰器 ...
- python中编写无参数decorator
Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数. 使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = de ...
- 处理python中的无类型变量的方法
1 可以用isinstance(obj, class)来判断 转载于:https://www.cnblogs.com/hustdc/p/7131957.html
- python编写装饰器_写python中的装饰器
python中的装饰器主要用于在已有函数实现功能前附加需要输出的信息,下面将用实例展示我如何写装饰器. 首先分别尝试写装饰器装饰一个无参函数和一个有参函数(被装饰函数仅输出,无返回值情况下) 1 de ...
- python高级语法装饰器_Python高级编程——装饰器Decorator超详细讲解上
Python高级编程--装饰器Decorator超详细讲解(上篇) 送你小心心记得关注我哦!! 进入正文 全文摘要 装饰器decorator,是python语言的重要特性,我们平时都会遇到,无论是面向 ...
- 在Python中什么是闭包?能做什么?
1.什么是闭包 当我们在外部函数中定义了一个内部函数,并且内部函数能够读取到外部函数内的变量,这种函数我们就称为闭包.简单来说,闭包就是能够读取外部函数内的变量的函数.闭包的架子大概是这样: def ...
- python里面的之前打过的记忆信息-python中的记忆:如何缓存函数的运行结果(1)
Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 使用称为"memoization"的强大而方便的缓存技术来加速您的Python程序. ...
- python有什么作用-Python中的闭包到底有什么用
1.global关键字的作用 如果在函数中需要修改全局变量,则需要使用该关键字,具体参见下面例子. variable=100 deffunction():print(variable) #在函数内不对 ...
最新文章
- KOAProgressBar
- Throwable是java.lang包中一个专门用来处理异常的类
- mysql数据库帐户_MySQL数据库用户帐号管理基础知识详解
- 复现经典:《统计学习方法》第 8 章 提升方法
- android P精简教程,华为EMUI 9.0发布:基于Android P打造 设置项精简10%
- Nginx Rewrite规则初探
- java手机号判断运营商_用Java对手机号所属运营商进行判断
- 补丁 检测系统_大云制造 | BCLinux For ARM64 V7.6操作系统正式发布
- 容器编排技术 -- Kubernetes kubectl 与 Docker 命令关系
- Android 6.0谷歌卡刷包,卡刷包走起:谷歌Nexus5升级安卓6.0/Android M教程
- 凯恩帝数控系统面板介绍_KND凯恩帝数控系统说明书
- 简单易用的运动控制卡(八):直线插补和手轮运动
- Fisher判别分析详解
- 计算机画大熊猫教案,大班美术画大熊猫教案
- Git版本管理工具使用知识汇总
- 人称代词的各种形式与用法
- 2022 ICPC Gran Premio de Mexico 1ra Fecha(一)
- C语言:小写字母与大写字母的转换
- C或C++中的isalpha、isalnum、islower 和 isupper函数的详解
- 【特征检测】BRISK特征提取算法