Multi-adorner _python in Python

Source: Internet
Author: User

Multiple adorners, that is, multiple adorners to modify the same object "actually not exactly, and look at the following detailed"

1. The adorner has no parameters:

Copy Code code as follows:

>>> def A (func):
print '%s ' () is post to-a '%func.func_name
def _first (*args,**kw):
print ' call ' is the function%s () in _first (). ' %func.func_name
return func (*ARGS,**KW)
Return _first


>>> def second (func):
print '%s ' () is post to second () '%func.func_name
def _second (*args,**kw):
print ' call ' is the function%s () in _second (). ' %func.func_name
return func (*ARGS,**KW)
Return _second


>>> @first
@second
def test (): Return to ' Hello World '

Test () is post to second ()
_second () is post to a ()
>>> 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 Code code as follows:

>>> def Test ():
Return to ' Hello World '

>>> Test=second (Test)
Test () is post to second ()
>>> Test
<function _second at 0x000000000316d3c8>
>>> Test=first (Test)
_second () is post to a ()
>>> 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 Code code as follows:

>>> def A (printresult=false):
def _first (func):
print '%s ' () is post to _first () '%func.func_name
def __first (*args,**kw):
print ' call ' is 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 ' () is post to _second () '%func.func_name
def __second (*args,**kw):
print ' call ' is 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 to ' Hello World '

Test () is 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 ().
>>>

On the 35th line, the output is called __second (), and the __second () is called with Test () and print test (), and then the print is returned to __first (), and the print statement print is __second ( ) returns none of the

It is equivalent to:

Copy Code code as follows:

>>> def Test ():
Return to ' Hello World '

>>> Test=second (True) (test)
Test () is 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 the project manager, you require that each code block must have a parameter check argstype and a responsibility check responsibilityregister, which requires two adorners to monitor the code block.

Copy Code code as follows:

#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 are the switches associated with this function, not the type-validation-related keyword parameters, all options:
Opt_usetypeofdefaultvalue=>bool:false, when True, a silent with no specified type
The type of the default value used by the parameter of the recognition 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 isn't 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
Type of #关于default parameter
If options[' Opt_usetypeofdefaultvalue ']:
For k,v in Defaults.items ():
#如果default The parameter type is not specified differently, use the
The type of the default value #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 ' 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)

There are no documents here, so the caller does not know that using the wrong call causes an error, which is Kate's responsibility.

Like the above, multiple adorners can be used when there are two separate tests of the code.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.