Various Python decorators and Python decorators

Source: Internet
Author: User
Tags python decorator

Various Python decorators and 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:

>>> def test(func):def _test():print 'Call the function %s().'%func.func_namereturn func()return _test>>> @testdef say():return 'hello world'>>> say()Call the function say().'hello world'>>> 

B. The decorated object has the following parameters:

>>> def test(func):def _test(*args,**kw):print 'Call the function %s().'%func.func_namereturn func(*args,**kw)return _test>>> @testdef 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:

>>> def test(printResult=False):def _test(func):def __test():print 'Call the function %s().'%func.func_nameif printResult:print func()else:return func()return __testreturn _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'>>> @testdef 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:

>>> def test(printResult=False):def _test(func):def __test(*args,**kw):print 'Call the function %s().'%func.func_nameif printResult:print func(*args,**kw)else:return func(*args,**kw)return __testreturn _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:

>>> def test(cls):def _test():clsName=re.findall('(\w+)',repr(cls))[-1]print 'Call %s.__init().'%clsNamereturn cls()return _test>>> @testclass sy(object):value=32>>> s=sy()Call sy.__init().>>> s<__main__.sy object at 0x0000000002C3E390>>>> s.value32>>> 

B. The decorated object has the following parameters:

>>> def test(cls):def _test(*args,**kw):clsName=re.findall('(\w+)',repr(cls))[-1]print 'Call %s.__init().'%clsNamereturn cls(*args,**kw)return _test>>> @testclass 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:

>>> def test(printValue=True):def _test(cls):def __test():clsName=re.findall('(\w+)',repr(cls))[-1]print 'Call %s.__init().'%clsNameobj=cls()if printValue:print 'value = %r'%obj.valuereturn objreturn __testreturn _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:

>>> def test(printValue=True):def _test(cls):def __test(*args,**kw):clsName=re.findall('(\w+)',repr(cls))[-1]print 'Call %s.__init().'%clsNameobj=cls(*args,**kw)if printValue:print 'value = %r'%obj.valuereturn objreturn __testreturn _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:

>>> class test(object):def __init__(self,func):self._func=funcdef __call__(self):return self._func()>>> @testdef say():return 'hello world'>>> say()'hello world'>>> 

B. The decorated object has the following parameters:

>>> class test(object):def __init__(self,func):self._func=funcdef __call__(self,*args,**kw):return self._func(*args,**kw)>>> @testdef 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:

>>> class test(object):def __init__(self,beforeinfo='Call function'):self.beforeInfo=beforeinfodef __call__(self,func):def _call():print self.beforeInforeturn func()return _call>>> @test()def say():return 'hello world'>>> say()Call function'hello world'>>> 

Or:

>>> class test(object):def __init__(self,beforeinfo='Call function'):self.beforeInfo=beforeinfodef __call__(self,func):self._func=funcreturn self._calldef _call(self):print self.beforeInforeturn self._func()>>> @test()def say():return 'hello world'>>> say()Call function'hello world'>>> 

B. The decorated object has the following parameters:

>>> class test(object):def __init__(self,beforeinfo='Call function'):self.beforeInfo=beforeinfodef __call__(self,func):def _call(*args,**kw):print self.beforeInforeturn 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:

>>> class test(object):def __init__(self,beforeinfo='Call function'):self.beforeInfo=beforeinfodef __call__(self,func):self._func=funcreturn self._calldef _call(self,*args,**kw):print self.beforeInforeturn 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:

>>> class test(object):def __init__(self,cls):self._cls=clsdef __call__(self):return self._cls()>>> @testclass sy(object):def __init__(self):self.value=32>>> s=sy()>>> s<__main__.sy object at 0x0000000003AAFA20>>>> s.value32>>> 

B. The decorated object has the following parameters:

>>> class test(object):def __init__(self,cls):self._cls=clsdef __call__(self,*args,**kw):return self._cls(*args,**kw)>>> @testclass 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:

>>> class test(object):def __init__(self,printValue=False):self._printValue=printValuedef __call__(self,cls):def _call():obj=cls()if self._printValue:print 'value = %r'%obj.valuereturn objreturn _call>>> @test(True)class sy(object):def __init__(self):self.value=32>>> s=sy()value = 32>>> s<__main__.sy object at 0x0000000003AB50B8>>>> s.value32>>> 

B. The decorated object has the following parameters:

>>> class test(object):def __init__(self,printValue=False):self._printValue=printValuedef __call__(self,cls):def _call(*args,**kw):obj=cls(*args,**kw)if self._printValue:print 'value = %r'%obj.valuereturn objreturn _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.

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.