Python成长之路【第七篇】:Python基础之装饰器
一、什么是装饰器
装饰:装饰既修饰,意指为其他函数添加新功能
器:器既函数
装饰器定义:本质就是函数,功能是为其他函数添加新功能
二、装饰器需要遵循的原则
1、不能修改装饰器的源代码(开放封闭原则)
2、为装饰器函数添加新功能后,不能修改函数的调用方式
三、实现装饰器的知识储备
装饰器 = 高阶函数 + 函数嵌套 + 闭包
四、高阶函数
高阶函数的定义:
1、函数接收的参数是一个函数名
2、函数的返回值是一个函数名
3、满足上述条件任意一个,都可以称为之高阶函数
1 def foo(): 2 print('我的函数名作为参数传给高阶函数') 3 def gao_jie1(func): 4 print('我就是高阶函数1,我接收的参数名是%s' %func) 5 func() 6 7 def gao_jie2(func): 8 print('我就是高阶函数2,我的返回值是%s' %func) 9 return func 10 11 gao_jie1(foo) 12 gao_jie2(foo)
高阶函数示范
1 #高阶函数应用1:把函数名当做参数传给高阶函数 2 import time 3 def foo(): 4 print('from the foo') 5 6 def timmer(func): 7 start_time=time.time() 8 func() 9 stop_time=time.time() 10 print('函数%s 运行时间是%s' %(func,stop_time-start_time)) 11 timmer(foo) 12 #总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式
把函数名当做参数传给高阶函数
1 #高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名 2 import time 3 def foo(): 4 print('from the foo') 5 6 def timmer(func): 7 start_time=time.time() 8 return func 9 stop_time=time.time() 10 print('函数%s 运行时间是%s' %(func,stop_time-start_time)) 11 foo=timmer(foo) 12 foo() 13 #总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能
函数返回值是函数名
高阶函数总结:
1、函数接收的参数是一个函数名
作用:在不修改函数源代码的前提下,为函数添加新功能
不足:会改变函数的调用方式
2、函数的返回值是一个函数名
作用:不修改函数的调用方式
不足:不能添加新功能
五、函数嵌套
def foo(name):print("from foo %s" %name)def ret():print("from ret")def bar():print("from bar")bar()ret()foo("Albert")
六、闭包
闭包:在一个作用域里放入定义变量,想当于打了一个包
def foo(name):def ret():print("123%s"%name)def bar():print("456%s"%name)bar()ret()foo("Albert")
七、没有参数的装饰器
没有参数的装饰器 = 高阶函数 + 函数嵌套
基本框架
# 这就是一个实现装饰器最基本的架子
def timer(func):def wrapper():func()return wrapper
加上参数
def timer(func):def wrapper(*args, **kwargs):func(*args, **kwargs)return wrapper
加上功能
import timedef timer(func):def wrapper(*args, **kwargs):s_time = time.time()func(*args, **kwargs)e_time = time.time()print("函数【%s】,运行的时间是%s"%(func, e_time - s_time))return wrapper
加上返回值
import timedef timer(func):def wrapper(*args, **kwargs):s_time = time.time()res = func(*args, **kwargs)e_time = time.time()print("函数【%s】,运行的时间是%s"%(func, e_time - s_time))return resreturn wrapper
使用装饰器
def cal(array):res = 0for i in array:res += ireturn rescal = timer(cal)
a = cal(range(10))
print(a)
语法糖@
@timer # @timer == cal = timer(cal)
def cal(array):res = 0for i in array:res += ireturn resa = cal(range(10))
print(a)
八、装饰器应用示例
1 user_list=[ 2 {'name':'Albert','passwd':'123'}, 3 {'name':'Seven','passwd':'123'}, 4 {'name':'Eric','passwd':'123'}, 5 {'name':'Mary','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 current_user['login']=True 22 res=func(*args,**kwargs) 23 return res 24 else: 25 print('用户名或者密码错误,重新登录') 26 27 return wrapper 28 29 @auth_deco 30 def index(): 31 print('欢迎来到主页面') 32 33 @auth_deco 34 def home(): 35 print('这里是你家') 36 37 def shopping_car(): 38 print('查看购物车啊亲') 39 40 def order(): 41 print('查看订单啊亲') 42 43 44 index() 45 # home()
无参装饰器
1 user_list=[ 2 {'name':'Albert','passwd':'123'}, 3 {'name':'Seven','passwd':'123'}, 4 {'name':'Eric','passwd':'123'}, 5 {'name':'Mary','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 else: 26 print('用户名或者密码错误,重新登录') 27 elif auth_type == 'ldap': 28 print('巴拉巴拉小魔仙') 29 res=func(*args,**kwargs) 30 return res 31 return wrapper 32 return auth_deco 33 34 35 #auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file') 36 #就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数 37 @auth(auth_type='file') 38 def index(): 39 print('欢迎来到主页面') 40 41 @auth(auth_type='ldap') 42 def home(): 43 print('这里是你家') 44 45 def shopping_car(): 46 print('查看购物车啊亲') 47 48 def order(): 49 print('查看订单啊亲') 50 51 index() 52 # home()
带参装饰器
九、超时装饰器
1 import sys,threading,time 2 3 class KThread(threading.Thread): 4 5 """A subclass of threading.Thread, with a kill() 6 7 method. 8 9 10 11 Come from: 12 13 Kill a thread in Python: 14 15 http://mail.python.org/pipermail/python-list/2004-May/260937.html 16 17 """ 18 19 def __init__(self, *args, **kwargs): 20 21 threading.Thread.__init__(self, *args, **kwargs) 22 23 self.killed = False 24 25 26 27 def start(self): 28 29 """Start the thread.""" 30 31 self.__run_backup = self.run 32 33 self.run = self.__run # Force the Thread to install our trace. 34 35 threading.Thread.start(self) 36 37 38 39 def __run(self): 40 41 """Hacked run function, which installs the 42 43 trace.""" 44 45 sys.settrace(self.globaltrace) 46 47 self.__run_backup() 48 49 self.run = self.__run_backup 50 51 52 53 def globaltrace(self, frame, why, arg): 54 55 if why == 'call': 56 57 return self.localtrace 58 59 else: 60 61 return None 62 63 64 65 def localtrace(self, frame, why, arg): 66 67 if self.killed: 68 69 if why == 'line': 70 71 raise SystemExit() 72 73 return self.localtrace 74 75 76 77 def kill(self): 78 79 self.killed = True 80 81 82 83 class Timeout(Exception): 84 85 """function run timeout""" 86 87 88 89 def timeout(seconds): 90 91 """超时装饰器,指定超时时间 92 93 若被装饰的方法在指定的时间内未返回,则抛出Timeout异常""" 94 95 def timeout_decorator(func): 96 97 """真正的装饰器""" 98 99 100 101 def _new_func(oldfunc, result, oldfunc_args, oldfunc_kwargs): 102 103 result.append(oldfunc(*oldfunc_args, **oldfunc_kwargs)) 104 105 106 107 def _(*args, **kwargs): 108 109 result = [] 110 111 new_kwargs = { # create new args for _new_func, because we want to get the func return val to result list 112 113 'oldfunc': func, 114 115 'result': result, 116 117 'oldfunc_args': args, 118 119 'oldfunc_kwargs': kwargs 120 121 } 122 123 thd = KThread(target=_new_func, args=(), kwargs=new_kwargs) 124 125 thd.start() 126 127 thd.join(seconds) 128 129 alive = thd.isAlive() 130 131 thd.kill() # kill the child thread 132 133 if alive: 134 135 raise Timeout(u'function run too long, timeout %d seconds.' % seconds) 136 137 else: 138 139 return result[0] 140 141 _.__name__ = func.__name__ 142 143 _.__doc__ = func.__doc__ 144 145 return _ 146 147 return timeout_decorator 148 149 150 @timeout(5) 151 152 def method_timeout(seconds, text): 153 154 print('start', seconds, text) 155 156 time.sleep(seconds) 157 158 print('finish', seconds, text) 159 160 return seconds 161 162 163 method_timeout(6,'asdfasdfasdfas')
查看代码
转载于:https://www.cnblogs.com/albert0924/p/8760575.html
Python成长之路【第七篇】:Python基础之装饰器相关推荐
- Python成长之路【第九篇】:Python基础之面向对象
一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程–>错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个人 ...
- (转)Python成长之路【第九篇】:Python基础之面向对象
一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程-->错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个 ...
- 【Python成长之路】如何用python开发自己的iphone应用程序,并添加至siri指令
哈喽大家好,我是鹏哥. 今天想记录的学习主题是 -- 基于pythonista3 app开发自己的iphone应用程序. ~~~上课铃~~~ (由于今天被小伙伴推荐了这首歌,因此就应他的要求,作为此文 ...
- python成长之路第三篇(2)_正则表达式
打个广告欢迎加入linux,python资源分享群群号:478616847 目录: 1.什么是正则表达式,python中得正则简介 2.re模块的内容 3.小练习 一.什么是正则表达式(re) 正则表 ...
- python学习之路-第七天-python面向对象编程简介
面向对象编程 在python中,同样是类和对象作为重要的组成部分. 而且在python中基本数据类型如int都是有封装类的,都有自己的方法,应该是和java里面的Integer类似吧 类包括域和方法: ...
- 我的Python成长之路---第三天---Python基础(13)---2016年1月16日(雾霾)
五.Python的常用的内置函数 Python为我们准备了大量的内置函数,如下图所示 这里我们只讨论红框内的内置函数 abs(x) 返回一个数的绝对值(模),参数可以是真说或浮点数 >>& ...
- 我的Python成长之路---第三天---Python基础(9)---2016年1月16日(雾霾)
一.集合 set和dict类似,也是一组key的集合,但不存储value.由于key不能重复,所以,在set中,没有重复的key. 集合和我们数学中集合的概念是一样的,也有交集,并集,差集,对称差集等 ...
- 我的Python成长之路---第五天---Python基础(17)---2016年1月30日(晴)
常用模块 1.模块介绍 模块,用一砣代码实现了某个功能的代码集合. 模块分为三种 自定义模块 内置标准模块(又称标准库) 开源模块 2.常用模块 time模块 time.time() import t ...
- 【Python成长之路】破解Boss直聘网站滑块验证
哈喽大家好,我是鹏哥. 今天要记录的内容是 -- 破解Boss直聘网站的滑块验证. -- 上 课 铃-- TuesdayBurak Yeter;Danelle Sandoval - Tuesday 1 ...
- 【Python成长之路】快速理解复制、浅拷贝、深拷贝
哈喽大家好,我是鹏哥. 今天想聊聊的主题是 -- 浅拷贝/深拷贝. ~~~上课铃~~~ 赤伶HITA - 赤伶 1 写在前面 浅拷贝.深拷贝的知识点,在python笔试和面试的过程中,经常被作为考题来 ...
最新文章
- 生物工程学报-微生物组测序与分析专刊-邀请函
- 数据结构 互换二叉树中所有结点的左右子树 C
- 第一章 TensorFlow基础——python语法(三)
- What happens when passing an non-exist text object to API
- Desktop OS Market Share: Windows 90% - Mac 9% - Linux 1%
- Netcdf 文件多属性,按照时间段导出代码示例
- Visual SourceSafe(VSS)使用手册(转载)
- c 正则去掉html标签,C#用正则表达式去掉Html中的script脚本和html标签
- Caffe学习:使用pycaffe读取mean.binaryproto文件参数
- 2008下mysql补丁_windows Server 2008 R2安装Mysql 8的打补丁顺序
- JS获取ul中li的值同步到搜索框
- 计算机英语手抄报活动主题,英语手抄报比赛方案
- 苹果cms简洁精美影视模板整站源码
- java 微信小程序 校园跑腿系统
- java swing 大球吃小球游戏 功能完善 完整代码 下载即可以运行
- Spectator view——Hololens第三人称视角技术的详细实现过程
- 用JAVA详解冒泡排序
- S60手机系统错误对照表
- AI通过儿童眼球运动,筛查胎儿酒精谱系障碍
- 每日遥感论文(森林退化)
热门文章
- android 入门-android自定义控件
- jquery --- 使用when方法等待2个异步事件结束后执行某一个函数.
- es6 --- 正确获取Generator函数内部的this对象使其可以使用new
- Python 杨辉三角形的简单实现
- ES6-13 正则方法、修饰符yus、UTF_16编码方式
- ES5-拓展 箭头函数的this、this的优先级
- Codeforces Round #554 Div.2 E - Neko and Flashback
- Apache不记录制定文件类型日志
- Android自带Monkey测试
- WCF跨域 这可能是由于试图以跨域方式访问服务而又没有正确的跨域策略,或策略不适用于 SOAP...