Python 装饰器归纳总结
来源:互联网 发布:淘宝店铺换ip有影响吗 编辑:程序博客网 时间:2024/06/05 17:00
实际应用中装饰器没少用,像flask的路由功能,都是用装饰器来挂上去的,不过平时装饰器都是看的网上的文章然后在用,自己没总结过
这次单独写一篇笔记,加深印象
先简单讲一下我理解的装饰器的两大特点
1:在不用修改原本函数的情况下,对原来函数的输出结果进行添加功能
2:装饰器是一个高阶函数,他的返回值,是一个函数
普通函数
首先来看个普通函数
def current_time():print ('2016.12.25')f=current_timef()print (current_time.__name__)
这是一个打印当前日期的函数,最后还会打印出函数名字
2016.12.25current_time
可以看到,能打印出函数名字,是因为我们在调用的时候,手工打印了出来,如果你要自动地打印,那你就要修改原本的函数了
这样简单的函数改改还不是问题,如果你在一个大项目里面涉及到很多要改的地方,估计就要吐了。
所以,装饰器就可以提现他的作用了
最简单的装饰器
def simple(f):def inside():print ('here in decorator for function %s'% f.__name__)return freturn inside#调用方法1: 这个是最直接的方法,用@语法糖,这个的作用,和调用方法3的原理是一模一样的,将本体函数current_time传给simple@simpledef current_time(): print ('now')current_time()#调用方法2: 这个需要理解下simple(current_time)了以后,就相当于已经取到返回的inside了,如果你需要执行的话,就在后面再加一对()def current_time(): print ('now')simple(current_time)()#调用方法3 : 装饰器的基本原理,将本体函数以参数的方式传递给装饰器def current_time(): print ('now')current_time=simple(current_time)current_time()
这样一个最简单的装饰器就完成了,当你调用current他的输出结果是
本体函数带参数的装饰器
def current_time(x,y):return x+ydef decorator(f):def wrapper(*args,**kw):return f(*args,**kw)*3return wrapper@decoratordef current_time(x,y):return (x+y)print (current_time(1,2))
可以看到,decorator就是我们装饰器的名字了,他的参数是你需要加强的函数(以下称为本体函数)
你还可以看到,wrapper是装饰器内部的函数,他用于加强功能
他的作用是:将本体函数的结果,乘以3
我们来看一下效果
这样,你原来输入的参数1和2,相加结果是3,但是经过装饰器以后,结果就是3倍了。
装饰器本身附带参数
用@来做装饰器,和语句current_time=wrapper(current_time)的作用是一毛一样的。
这里需要特别记住:@这个语法,在这种情况下,只能相当于,将本体函数(这一个参数)传入装饰器函数,没法附带其他的内容
比如,你没法使用 @decorator( 'test_text' ) 这样的语法,他会提示参数错误的。
当然,你如果强行用current_time = decorator(current_time , 'test_text' )这样的写法,也是可以达到同时传入其他参数的目的
但是,这写法的繁琐程度和不用装饰器,没啥区别。
所以,我们引入了带参数的装饰器
平时用的最多的就是flask的路由装饰器了
比如最简单的flask路由
@app.route('/')def index(): return 'hello world'
那要实现这样的功能,如何修改装饰器呢?
这就需要再包括一层装饰器了
def top(text):def decorator(f):def wrapper(*args,**kw):print (text+' of top')return f(*args,**kw)*3return wrapperreturn decorator@top('text for test')def current_time(x,y):return (x+y)print (current_time(1,2))
这样,你的装饰器就可以随意添加你想要加的内容了
效果看下
e:\atry>python de.pytext for test of top9
这样的语句的简单理解写法是 current_time = top('text for test')(current_time)
也就是,先执行 top('text for test'),他返回decorator函数,然后,decorator函数再加上后面的(current_time)作为参数传入
需要注意的地方, name属性已改变
这里要额外提一下,这样装饰器,他的本体参数的__name__属性已改变,如果碰到一些和函数名字撤上关系的功能时,会引发错误
先看名字被改变的测试
print (current_time.__name__)他打印出的结果是 wrapper,也就是,原来的函数名字已经变成了wrapper
那如何规避这个问题呢?可以用functools里面的wrapper功能,如下
import functoolsdef current_time(x,y):return x+ydef top(text):def decorator(f):@functools.wraps(f)def wrapper(*args,**kw):print (text+' of top')return f(*args,**kw)*3return wrapperreturn decorator@top('text for test')def current_time(x,y):return (x+y)print (current_time(1,2))print (current_time.__name__)
这样,做出来的程序,他的名字就不会被修改了
多重装饰器的先后顺序
有时候你会看到,一个函数上面挂了好几个装饰器,那他们是否有先后顺序呢?肯定有的,我们来看看多重装饰器是从上往下还是从下往上开始执行
def add_before(f):def wrapper():print (f()+' add_before decorator')return f()+' add_before decorator'return wrapperdef add_later(f):def wrapper():# print (f()+' add_later decorator')return f()+' add_later decorator'return wrapper@add_before@add_laterdef test():return 'here in test'test()
通过下面的效果图,你可以看到,他是先被add_later 装饰器进行了作用,再进行add_before装饰器作用
也就是从最靠近本体函数的地方开始起装饰器作用
这样,装饰器基本的概念就完全了,其他的具体应用,也是基于这些原理之上的。
- Python 装饰器归纳总结
- python装饰器学习总结
- Python装饰器模式学习总结
- Python中装饰器的总结
- Python闭包与装饰器总结
- Python 装饰器记录总结 (终极版)
- python总结(一):AOP与装饰器
- python学习总结归纳目录
- python装饰器装饰类
- [python]python装饰器
- Python装饰器学习
- Python装饰器
- python 装饰器
- Python装饰器
- python 装饰器 应用
- python 装饰器2
- Python装饰器学习
- python装饰器
- Can a Compound Index serve multiple queries
- 【备忘】北风网Android应用实战淘宝网手机客户端全程实录 下载
- AndroidAnnotations注解说明
- pat-a1084. Broken Keyboard (20)
- 常用的表扩展字段方案
- Python 装饰器归纳总结
- 【Leetcode】38. Count and Say
- Docker完全解析 一、Docker简介
- Ubuntu安装Tomcat8
- OP整流电路
- FZU 1036 四塔问题
- 知识库--StandardContextMapper(60)
- 6
- 第一次使用Android Studio时你应该知道的一切配置