A detailed explanation of various decorators in Python and a detailed explanation of Python decorators

Source: Internet
Author: User
Tags python decorator

A detailed explanation of various decorators in Python and a detailed explanation of Python decorators

The Python decorator consists of two parts: one is the definition of the decorator itself, and the other is the definition of the decorator object.

I. Functional decorators: The decorators are a function.

1. decoration function: the decorated object is a function.

[1] No parameters for the decorator:

A. the decorated object has no parameters:
Copy codeThe Code is as follows:
>>> Def test (func ):
Def _ test ():
Print 'Call the function % s (). '% func. func_name
Return func ()
Return _ test

>>> @ Test
Def say (): return 'Hello world'

>>> Say ()
Call the function say ().
'Hello world'
>>>

B. The decorated object has the following parameters:
Copy codeThe Code is as follows:
>>> Def test (func ):
Def _ test (* args, ** kw ):
Print 'Call the function % s (). '% func. func_name
Return func (* args, ** kw)
Return _ test

>>> @ Test
Def left (Str, Len ):
# The parameters of _ test can be '(Str, Len)' in this case.
Return Str [: Len]

>>> Left ('Hello world', 5)
Call the function left ().
'Hello'
>>>

[2] The decorator has the following parameters:

A. the decorated object has no parameters:
Copy codeThe Code is as follows:
>>> Def test (printResult = False ):
Def _ test (func ):
Def _ test ():
Print 'Call the function % s (). '% func. func_name
If printResult:
Print func ()
Else:
Return func ()
Return _ test
Return _ test

>>> @ Test (True)
Def say (): return 'Hello world'

>>> Say ()
Call the function say ().
Hello world
>>> @ Test (False)
Def say (): return 'Hello world'

>>> Say ()
Call the function say ().
'Hello world'
>>> @ Test ()
Def say (): return 'Hello world'

>>> Say ()
Call the function say ().
'Hello world'
>>> @ Test
Def say (): return 'Hello world'

>>> Say ()

Traceback (most recent call last ):
File "<pyshell #224>", line 1, in <module>
Say ()
TypeError: _ test () takes exactly 1 argument (0 given)
>>>

The last two examples in the above Code show that when the decorator has parameters, even if you enable the default parameters of the decorator without passing in new values, there must be a pair of parentheses, otherwise, the compiler will pass func directly to test () instead of _ test ()

B. The decorated object has the following parameters:
Copy codeThe Code is as follows:
>>> Def test (printResult = False ):
Def _ test (func ):
Def _ test (* args, ** kw ):
Print 'Call the function % s (). '% func. func_name
If printResult:
Print func (* args, ** kw)
Else:
Return func (* args, ** kw)
Return _ test
Return _ test

>>> @ Test ()
Def left (Str, Len ):
# The parameters of _ test can be '(Str, Len)' in this case.
Return Str [: Len]

>>> Left ('Hello world', 5)
Call the function left ().
'Hello'
>>> @ Test (True)
Def left (Str, Len ):
# The parameters of _ test can be '(Str, Len)' in this case.
Return Str [: Len]

>>> Left ('Hello world', 5)
Call the function left ().
Hello
>>>

 
2. decoration class: the object to be decorated is a class.

[1] No parameters for the decorator:

A. the decorated object has no parameters:
Copy codeThe Code is as follows:
>>> Def test (cls ):
Def _ test ():
ClsName = re. findall ('(\ w +)', repr (cls) [-1]
Print 'call % s. _ init (). '% clsName
Return cls ()
Return _ test

>>> @ Test
Class sy (object ):
Value = 32


>>> S = sy ()
Call sy. _ init ().
>>> S
<__ Main _. sy object at 0x0000000002C3E390>
>>> S. value
32
>>>

B. The decorated object has the following parameters:
Copy codeThe Code is as follows:
>>> Def test (cls ):
Def _ test (* args, ** kw ):
ClsName = re. findall ('(\ w +)', repr (cls) [-1]
Print 'call % s. _ init (). '% clsName
Return cls (* args, ** kw)
Return _ test

>>> @ Test
Class sy (object ):
Def _ init _ (self, value ):
# The parameters of _ test can be '(value)' in this case.
Self. value = value


>>> S = sy ('Hello World ')
Call sy. _ init ().
>>> S
<__ Main _. sy object at 0x0000000003AF7748>
>>> S. value
'Hello world'
>>>

[2] The decorator has the following parameters:

A. the decorated object has no parameters:
Copy codeThe Code is as follows:
>>> Def test (printValue = True ):
Def _ test (cls ):
Def _ test ():
ClsName = re. findall ('(\ w +)', repr (cls) [-1]
Print 'call % s. _ init (). '% clsName
Obj = cls ()
If printValue:
Print 'value = % R' % obj. value
Return obj
Return _ test
Return _ test

>>> @ Test ()
Class sy (object ):
Def _ init _ (self ):
Self. value = 32


>>> S = sy ()
Call sy. _ init ().
Value = 32
>>> @ Test (False)
Class sy (object ):
Def _ init _ (self ):
Self. value = 32


>>> S = sy ()
Call sy. _ init ().
>>>

B. The decorated object has the following parameters:
 Copy codeThe Code is as follows:
>>> Def test (printValue = True ):
Def _ test (cls ):
Def _ test (* args, ** kw ):
ClsName = re. findall ('(\ w +)', repr (cls) [-1]
Print 'call % s. _ init (). '% clsName
Obj = cls (* args, ** kw)
If printValue:
Print 'value = % R' % obj. value
Return obj
Return _ test
Return _ test

>>> @ Test ()
Class sy (object ):
Def _ init _ (self, value ):
Self. value = value


>>> S = sy ('Hello World ')
Call sy. _ init ().
Value = 'Hello world'
>>> @ Test (False)
Class sy (object ):
Def _ init _ (self, value ):
Self. value = value


>>> S = sy ('Hello World ')
Call sy. _ init ().
>>>
 


Ii. class-based decorator: the decorator itself is a class, which uses _ init _ () and _ call _ () to implement its functions.

1. decoration function: the decorated object is a function.

[1] No parameters for the decorator:

A. the decorated object has no parameters:
Copy codeThe Code is as follows:
>>> Class test (object ):
Def _ init _ (self, func ):
Self. _ func = func
Def _ call _ (self ):
Return self. _ func ()


>>> @ Test
Def say ():
Return 'Hello world'

>>> Say ()
'Hello world'
>>>

B. The decorated object has the following parameters:
Copy codeThe Code is as follows:
>>> Class test (object ):
Def _ init _ (self, func ):
Self. _ func = func
Def _ call _ (self, * args, ** kw ):
Return self. _ func (* args, ** kw)


>>> @ Test
Def left (Str, Len ):
# The parameters of _ call _ can be '(self, Str, Len)' in this case.
Return Str [: Len]

>>> Left ('Hello world', 5)
'Hello'
>>>

[2] The decorator has Parameters

A. the decorated object has no parameters:
Copy codeThe Code is as follows:
>>> Class test (object ):
Def _ init _ (self, beforeinfo = 'call function '):
Self. beforeInfo = beforeinfo
Def _ call _ (self, func ):
Def _ call ():
Print self. beforeInfo
Return func ()
Return _ call


>>> @ Test ()
Def say ():
Return 'Hello world'

>>> Say ()
Call function
'Hello world'
>>>

Or:
Copy codeThe Code is as follows:
>>> Class test (object ):
Def _ init _ (self, beforeinfo = 'call function '):
Self. beforeInfo = beforeinfo
Def _ call _ (self, func ):
Self. _ func = func
Return self. _ call
Def _ call (self ):
Print self. beforeInfo
Return self. _ func ()


>>> @ Test ()
Def say ():
Return 'Hello world'

>>> Say ()
Call function
'Hello world'
>>>

B. The decorated object has the following parameters:
 Copy codeThe Code is as follows:
>>> Class test (object ):
Def _ init _ (self, beforeinfo = 'call function '):
Self. beforeInfo = beforeinfo
Def _ call _ (self, func ):
Def _ call (* args, ** kw ):
Print self. beforeInfo
Return func (* args, ** kw)
Return _ call


>>> @ Test ()
Def left (Str, Len ):
# The parameters of _ call can be '(Str, Len)' in this case.
Return Str [: Len]

>>> Left ('Hello world', 5)
Call function
'Hello'
>>>
 

Or:
 Copy codeThe Code is as follows:
>>> Class test (object ):
Def _ init _ (self, beforeinfo = 'call function '):
Self. beforeInfo = beforeinfo
Def _ call _ (self, func ):
Self. _ func = func
Return self. _ call
Def _ call (self, * args, ** kw ):
Print self. beforeInfo
Return self. _ func (* args, ** kw)


>>> @ Test ()
Def left (Str, Len ):
# The parameters of _ call can be '(self, Str, Len)' in this case.
Return Str [: Len]

>>> Left ('Hello world', 5)
Call function
'Hello'
>>>
 
2. decoration class: The decorated object is a class.

[1] No parameters for the decorator:

A. the decorated object has no parameters:
Copy codeThe Code is as follows:
>>> Class test (object ):
Def _ init _ (self, cls ):
Self. _ cls = cls
Def _ call _ (self ):
Return self. _ cls ()


>>> @ Test
Class sy (object ):
Def _ init _ (self ):
Self. value = 32


>>> S = sy ()
>>> S
<__ Main _. sy object at 0x0000000003AAFA20>
>>> S. value
32
>>>

B. The decorated object has the following parameters:
 Copy codeThe Code is as follows:
>>> Class test (object ):
Def _ init _ (self, cls ):
Self. _ cls = cls
Def _ call _ (self, * args, ** kw ):
Return self. _ cls (* args, ** kw)


>>> @ Test
Class sy (object ):
Def _ init _ (self, value ):
# The parameters of _ call _ can be '(self, value)' in this case.
Self. value = value


>>> S = sy ('Hello World ')
>>> S
<__ Main _. sy object at 0x0000000003AAFA20>
>>> S. value
'Hello world'
>>>
 

[2] The decorator has the following parameters:

A. the decorated object has no parameters:
Copy codeThe Code is as follows:
>>> Class test (object ):
Def _ init _ (self, printValue = False ):
Self. _ printValue = printValue
Def _ call _ (self, cls ):
Def _ call ():
Obj = cls ()
If self. _ printValue:
Print 'value = % R' % obj. value
Return obj
Return _ call


>>> @ Test (True)
Class sy (object ):
Def _ init _ (self ):
Self. value = 32


>>> S = sy ()
Value = 32
>>> S
<__ Main _. sy object at 0x0000000003AB50B8>
>>> S. value
32
>>>

B. The decorated object has the following parameters:
 Copy codeThe Code is as follows:
>>> Class test (object ):
Def _ init _ (self, printValue = False ):
Self. _ printValue = printValue
Def _ call _ (self, cls ):
Def _ call (* args, ** kw ):
Obj = cls (* args, ** kw)
If self. _ printValue:
Print 'value = % R' % obj. value
Return obj
Return _ call


>>> @ Test (True)
Class sy (object ):
Def _ init _ (self, value ):
# The parameters of _ call can be '(value)' in this case.
Self. value = value


>>> S = sy ('Hello World ')
Value = 'Hello world'
>>> S
<__ Main _. sy object at 0x0000000003AB5588>
>>> S. value
'Hello world'
>>>
 

Conclusion: [1] @ decorator when there is no parentheses behind it (that is, when the decorator has no parameters), the effect is equivalent to defining func or cls first, then perform the value assignment operation func = decorator (func) or cls = decorator (cls );

[2] @ decorator when there are Parentheses (that is, when the decorator has parameters), the effect is equivalent to defining func or cls first, and then performing the value assignment operation func = decorator (decoratorArgs) (func) or cls = decorator (decoratorArgs) (cls );

[3] After you revalue func or cls, func or cls is no longer the func or cls defined in the original definition, but an executable body, you only need to pass in the parameter to call, func (args) => return value or output, cls (args) => object of cls;

[4] The execution bodies returned by assigning values are diverse, including closures or external functions. When decorated with a class, they can also be internal methods and functions of the class;

[5] In addition, to really understand the decorations, you must understand func. func_code.co_varnames, func. func_defaults: you can restore the parameter list of func beyond the definition of func. In addition, the keyword parameter is called, not the definition of func, in the definition of func, only parameters with default values are connected by equal signs. They are not necessarily keyword parameters, because they can still be passed by location.

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.