1. Adorner no parameters: Codego.net
>>> def First (func):
print '%s () was post to first () '%func.func_name
def _first (*args,**kw):
print ' Call the function%s () in _first (). ' %func.func_name
return func (*ARGS,**KW)
Return _first
>>> def second (func):
print '%s () was post to second () '%func.func_name
def _second (*args,**kw):
print ' Call the function%s () in _second (). ' %func.func_name
return func (*ARGS,**KW)
Return _second
>>> @first
@second
def test (): Return ' Hello World '
Test () was post to second ()
_second () is post to first ()
>>> Test ()
Call the function _second () in _first ().
Call the function test () in _second ().
' Hello World '
>>>
In fact it is equivalent to the following code:
Copy the code code as follows:
>>> def Test ():
Return ' Hello World '
>>> Test=second (Test)
Test () was post to second ()
>>> Test
<function _second at 0x000000000316d3c8>
>>> Test=first (Test)
_second () is post to first ()
>>> Test
<function _first at 0x000000000316d358>
>>> Test ()
Call the function _second () in _first ().
Call the function test () in _second ().
' Hello World '
>>>
2. The adorner has parameters:
Copy the code code as follows:
>>> def first (Printresult=false):
def _first (func):
print '%s () was post to _first () '%func.func_name
def __first (*args,**kw):
print ' Call the function%s () in __first (). '%\
Func.func_name
If Printresult:
Print func (*args,**kw), ' #print in __first (). '
Else
return func (*ARGS,**KW)
Return __first
Return _first
>>> def second (printresult=false):
def _second (func):
print '%s () was post to _second () '%func.func_name
def __second (*args,**kw):
print ' Call the function%s () in __second (). '%\
Func.func_name
If Printresult:
Print func (*args,**kw), ' #print in __second (). '
Else
return func (*ARGS,**KW)
Return __second
Return _second
>>> @first (True)
@second (True)
def test ():
Return ' Hello World '
Test () was post to _second ()
__second () is post to _first ()
>>> Test ()
Call the function __second () in __first ().
Call the function test () in __second ().
Hello World #print in __second ().
None #print in __first ().
>>>
As above, the 35th line is output after calling __second (), and __second () calls test () and print test (), and then returns to __first () to proceed with print, and the print statement print is __second ( ) returns the None
It is equivalent to:
>>> def Test ():
Return ' Hello World '
>>> Test=second (True) (test)
Test () was post to _second ()
>>>
>>> Test
<function __second at 0x000000000316d2e8>
>>> Test=first (True) (test)
__second () is post to _first ()
>>> Test
<function __first at 0x0000000003344c18>
>>>
3. Multi-Adorner application:
For example, if you are a project manager, you require that each block of code must have parameter checking Argstype and a responsibility check responsibilityregister, which requires two adorners to supervise this block of code.
#coding =utf-8
Import Os,sys,re
From collections Import Ordereddict
def argstype (*argtypes,**kwtypes):
U ' Argstype (*argtypes,**kwtypes)
options=[(' Opt_usetypeofdefaultvalue ', False)]
The following switches are related to this function, not the keyword parameters associated with type checking, all options:
Opt_usetypeofdefaultvalue=>bool:false, when True, will have a default of the specified type
The value parameter uses the type of its default value
‘‘‘
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
#将 all the Options keyword arguments in the parameter type keyword parameter
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 the type of parameter
If options[' Opt_usetypeofdefaultvalue ']:
For k,v in Defaults.items ():
#如果default parameter type is not specified otherwise, use the
The type of the default value of the #default parameter
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 is 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 _argstype
def 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)
Python Multi-Adorner