Python多重装饰器
来源:互联网 发布:js绑定click事件 编辑:程序博客网 时间:2024/06/11 07:57
多重装饰器,即多个装饰器修饰同一个对象【实际上并非完全如此,且看下文详解】
1.装饰器无参数:
1 >>> def first(func): 2 print '%s() was post to first()'%func.func_name 3 def _first(*args,**kw): 4 print 'Call the function %s() in _first().'%func.func_name 5 return func(*args,**kw) 6 return _first 7 8 9 >>> def second(func):10 print '%s() was post to second()'%func.func_name11 def _second(*args,**kw):12 print 'Call the function %s() in _second().'%func.func_name13 return func(*args,**kw)14 return _second15 16 17 >>> @first18 @second19 def test():return 'hello world'20 21 test() was post to second()22 _second() was post to first()23 >>> test()24 Call the function _second() in _first().25 Call the function test() in _second().26 'hello world'27 >>>
实际上它是相当于下面的代码:
1 >>> def test(): 2 return 'hello world' 3 4 >>> test=second(test) 5 test() was post to second() 6 >>> test 7 <function _second at 0x000000000316D3C8> 8 >>> test=first(test) 9 _second() was post to first()10 >>> test11 <function _first at 0x000000000316D358>12 >>> test()13 Call the function _second() in _first().14 Call the function test() in _second().15 'hello world'16 >>>
2.装饰器有参数:
1 >>> def first(printResult=False): 2 def _first(func): 3 print '%s() was post to _first()'%func.func_name 4 def __first(*args,**kw): 5 print 'Call the function %s() in __first().'%\ 6 func.func_name 7 if printResult: 8 print func(*args,**kw),'#print in __first().' 9 else:10 return func(*args,**kw)11 return __first12 return _first13 14 >>> def second(printResult=False):15 def _second(func):16 print '%s() was post to _second()'%func.func_name17 def __second(*args,**kw):18 print 'Call the function %s() in __second().'%\19 func.func_name20 if printResult:21 print func(*args,**kw),'#print in __second().'22 else:23 return func(*args,**kw)24 return __second25 return _second26 27 >>> @first(True)28 @second(True)29 def test():30 return 'hello world'31 32 test() was post to _second()33 __second() was post to _first()34 >>> test()35 Call the function __second() in __first().36 Call the function test() in __second().37 hello world #print in __second().38 None #print in __first().39 >>>
如上,第35行输出后调用__second(),而__second()中又调用了test()并print test(),而后返回__first()中继续执行print,而这个print语句print的内容是__second()返回的None
它等同于:
>>> def test(): return 'hello world'>>> test=second(True)(test)test() was post to _second()>>> >>> test<function __second at 0x000000000316D2E8>>>> test=first(True)(test)__second() was post to _first()>>> test<function __first at 0x0000000003344C18>>>>
3.多重装饰器的应用:
比如你是项目经理,你要求每一个代码块都必须有参数检查ArgsType和责任检查ResponsibilityRegister,这样就需要两个装饰器对此代码块进行监督。
#coding=utf-8import os,sys,refrom collections import OrderedDictdef ArgsType(*argTypes,**kwTypes): u'''ArgsType(*argTypes,**kwTypes) options=[('opt_UseTypeOfDefaultValue',False)] 以下为本函数相关的开关,并非类型检验相关的关键字参数,所有options: opt_UseTypeOfDefaultValue=>bool:False,为True时,将对没有指定类型的带默 认值的参数使用其默认值的类型 ''' def _ArgsType(func): #确定所有的parameter name argNames=func.func_code.co_varnames[:func.func_code.co_argcount] #确定所有的default parameter defaults=func.func_defaults if defaults: defaults=dict(zip(argNames[-len(defaults):],defaults)) else:defaults=None #将“参数类型关键字参数”中的所有“options关键字参数”提出 options=dict() for option,default in [('opt_UseTypeOfDefaultValue',False)]: options[option]=kwTypes.pop(option,default) #argTypes和kwTypes的总长度应该与argNames一致 if len(argTypes)+len(kwTypes)>len(argNames): raise Exception('Too much types to check %s().'%func.func_name) #所有kwTypes中的键不能覆盖在argTypes中已经占用的names if not set(argNames[len(argTypes):]).issuperset( set(kwTypes.keys())): raise Exception('There is some key in kwTypes '+ 'which is not in argNames.') #确定所有的参数应该有的types types=OrderedDict() for name in argNames:types[name]=None if len(argTypes): for i in range(len(argTypes)): name=argNames[i] types[name]=argTypes[i] else: for name,t in kwTypes.items(): types[name]=t if len(kwTypes): for name,t in kwTypes.items(): types[name]=t #关于default parameter的type if options['opt_UseTypeOfDefaultValue']: for k,v in defaults.items(): #如果default parameter的type没有另外指定,那么就使用 #default parameter的default value的type if types[k]==None: types[k]=type(v) def __ArgsType(*args,**kw): #order the args Args=OrderedDict() #init keys for name in argNames:Args[name]=None #init default values if defaults is not None: for k,v in defaults.items(): Args[k]=v #fill in all args for i in range(len(args)): Args[argNames[i]]=args[i] #fill in all keyword args for k,v in kw.items(): Args[k]=v #check if there is some None in the values if defaults==None: for k in Args: if Args[k]==None: if defaults==None: raise Exception(('%s() needs %r parameter, '+ 'which was not given')%(func.func_name,k)) else: if not defaults.has_key(k): raise Exception(('Parameter %r of %s() is'+ ' not a default parameter')%\ (k,func.func_name)) #check all types for k in Args: if not isinstance(Args[k],types[k]): raise TypeError(('Parameter %r of %s() must be '+ 'a %r object, but you post: %r')%\ (k,func.func_name,types[k],Args[k])) return func(*args,**kw) return __ArgsType return _ArgsTypedef ResponsibilityRegister(author): def _ResponsibilityRegister(func): def __ResponsibilityRegister(*args,**kw): try: return func(*args,**kw) except Exception as e: print ("Something is wrong, It's %s's responsibility."%\ author).center(80,'*') raise e return __ResponsibilityRegister return _ResponsibilityRegister@ResponsibilityRegister('Kate')@ArgsType(str,int)def left(Str,Len=1): return Str[:Len]print 'Good calling:'print left('hello world',8)print 'Bad calling:'print left(3,7)
这里没有文档,所以调用者不知道,使用了错误的调用,导致出错,这是Kate的责任。
像上面这种,对代码有两种互不相干的检验时,就可以使用多重装饰器。
阅读全文
0 0
- Python多重装饰器
- python 多重装饰器执行顺序
- python装饰器装饰类
- [python]python装饰器
- Python装饰器学习
- Python装饰器
- python 装饰器
- Python装饰器
- python 装饰器 应用
- python 装饰器2
- Python装饰器学习
- python装饰器
- python装饰器
- python 装饰器入门
- python装饰器
- python装饰器
- python 装饰器'@'
- python装饰器
- flash动画老鼠
- 字符编码
- MyBatis的Mapper接口以及Example的实例函数及详解
- Linux下程序的编译过程
- ExtJS 使用技巧(持续更新)
- Python多重装饰器
- Nginx+php+mysql+wordpress搭建自己的博客站点
- vs2008无法使用查找功能了, 查找进行的过程中被停止
- JVM调优定位最耗cpu的线程
- 201
- 使用SimpleDateFormat实现String、Date互转
- NGINX原理 之 SLAB分配机制
- HTTP与HTTPS握手的那些事
- 一篇对Spring Security框架理解的好文(注意一下评论区)