python之路(九)-函数装饰器
2016-01-25 11:23
656 查看
装饰器
某公司的基础业务平台如下:
各业务部门是这样调用的:
随着公司的规模扩大,每个业务部门的研发越来越多,为了规范管理,此时需要各业务部门的研发在调用以上方法之前先登陆,认证成功后方可调用,有如下方案:
1.让业务部门自己写登陆程序。
2.基础平台写好认证程序,告诉业务部门研发在调用方法前先调用验证的方法。
3.基础平台写好认证程序,并在每个方法内加入该验证程序。
4.基础平台写好认证程序,然后再不改动原方法并且不改变业务部门调用原方法方式实现认证。
分析下以上方法,方法1肯定不合适,业务部门自己验证自己显然不符合要求。方法2每个业务部门都改变了调用方法,也不合适。方法3虽然没有改变业务部门调用方法但是在每个方法内加入同样的多行代码太复杂。方法4非常好,此时就需要用到函数装饰器具。
示例:
以上装饰器中,
loginsuccessfull!
yournameisTomcat
#我们说了inner函数就是装饰器重新包装的被装饰的函数,所以inner函数的参数就是原函数f1的参数
更叼的装饰器(装饰器具中带参数):
某公司的基础业务平台如下:
deff1(): print('这是f1业务平台') deff2(): print('这是f2业务平台') deff3(): print('这是f3业务平台') deff4(): print('这是f4业务平台') deff5(): print('这是f5业务平台')
各业务部门是这样调用的:
#f1业务部门调用 f1() #f2业务部门调用 f2() #f1业务部门调用 f3() #f4业务部门调用 f4() #f5业务部门调用 f5()
随着公司的规模扩大,每个业务部门的研发越来越多,为了规范管理,此时需要各业务部门的研发在调用以上方法之前先登陆,认证成功后方可调用,有如下方案:
1.让业务部门自己写登陆程序。
2.基础平台写好认证程序,告诉业务部门研发在调用方法前先调用验证的方法。
3.基础平台写好认证程序,并在每个方法内加入该验证程序。
4.基础平台写好认证程序,然后再不改动原方法并且不改变业务部门调用原方法方式实现认证。
分析下以上方法,方法1肯定不合适,业务部门自己验证自己显然不符合要求。方法2每个业务部门都改变了调用方法,也不合适。方法3虽然没有改变业务部门调用方法但是在每个方法内加入同样的多行代码太复杂。方法4非常好,此时就需要用到函数装饰器具。
示例:
defwrapper(func):
definner():
print('验证成功')
func()
returninner
@wrapper
deff1():
print('这是f1业务平台')
@wrapper
deff2():
print('这是f2业务平台')
@wrapper
deff3():
print('这是f3业务平台')
@wrapper
deff4():
print('这是f4业务平台')
@wrapper
deff5():
print('这是f5业务平台')
#f1业务部门调用 f1() #f2业务部门调用 f2() #f1业务部门调用 f3() #f4业务部门调用 f4() #f5业务部门调用 f5()
以上装饰器中,
@wrapper表示要对下面的函数进行装饰,此时要做的操作是:首先执行wrapper函数,然后将要装饰的函数名作为参数传给wrapper函数,wrapper函数的内容是定义了一个inner函数(注意只是定义了inner函数,并未执行),inner函数内先执行登陆功能函数,然后在执行被装饰的函数,所以wrapper函数相当于重新包装了一下被装饰的函数,比如f1函数,在包装f1函数的时候先执行了验证的方法,然后再执行f1函数。此时如果业务部门执行f1函数,那么他执行的是被包装后的函数及inner函数。此为装饰器。 问题:被装饰的函数如果有参数呢? 示例1:一个参数
defwrapper(func):
definner(args):
print('loginsuccessfull!')
func(args)
returninner
@wrapper
deff1(args):
print('yournameis%s'%args)
f1('Tomcat')
#输出结果:
loginsuccessfull!
yournameisTomcat
#我们说了inner函数就是装饰器重新包装的被装饰的函数,所以inner函数的参数就是原函数f1的参数
示例2:两个参数
defwrapper(func):
definner(args1,args2):
print('loginsuccessfull!')
func(args1,args2)
returninner
@wrapper
deff1(args1,args2):
print('yournameis%sandyourageis%s'%(args1,args2))
f1('Tomcat','23')
#输出结果:
loginsuccessfull!
yournameisTomcatandyourageis23
示例3:三个参数
defwrapper(func):
definner(*args,**kwargs):
print('loginsuccessfull!')
func(*args,**kwargs)
returninner
@wrapper
deff1(args1,args2,args3):
print('yournameis%sandyourageis%s,%s'%(args1,args2,args3))
f1('Tomcat','23','boy')
#输出结果:
loginsuccessfull!
yournameisTomcatandyourageis23,boy
更叼的装饰器(装饰器具中带参数):
#!/usr/bin/envpython
#coding:utf-8
defBefore(request,kargs):
print'before'
defAfter(request,kargs):
print'after'
defFilter(before_func,after_func):
defouter(main_func):
defwrapper(request,kargs):
before_result=before_func(request,kargs)
if(before_result!=None):
returnbefore_result;
main_result=main_func(request,kargs)
if(main_result!=None):
returnmain_result;
after_result=after_func(request,kargs)
if(after_result!=None):
returnafter_result;
returnwrapper
returnouter
@Filter(Before,After)
defIndex(request,kargs):
print'index'
相关文章推荐
- python之路(八)-迭代器&生成器
- python之路(七)-递归算法
- learn python the hard way(笨办法学python) 练习40 类的用法
- 在python3.3后urllib2已经不能再用,只能用urllib.request来代替
- python 常用模块
- python list解析, map,生成器表达式
- python 函数
- python废话五:python获取本机信息
- 关于python-NameError: global name 'platform' is not defined
- Python开发基础-day1
- Python字符编码详解
- 详解Python验证码识别
- Python--多进程
- python废话四:python的import引入模块
- python 帮助和导入路径
- 谈谈Python进行验证码识别的一些想法
- Python网站验证码识别
- Python中变量的作用域(variable scope)
- 基于Python Shell获取hostname和fqdn释疑
- python-dict