Python Multi-Adorner

Source: Internet
Author: User

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

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.