Python decorator @property

Source: Internet
Author: User
Tags closure python decorator

Adorner example

defW1 (func):definner ():Print('... Verify Permissions ...') func ()returnINNER@W1defF1 ():Print('F1 called') @w1defF2 ():Print('F2 called') F1 () F2 ()

Output Result:

... Verify permissions ... F1 called ... Verify permissions ... f2 called

When the F1,F2 function is called, validation is performed first. Through a closure function w1, call the function through the keyword @w1, the f1,f2 completed the decoration.

When the Python interpreter interprets @w1, the W1 function is called, and the name of the modified function is passed in (for example, F1), when the W1 function is executed, the inner function is returned directly, and the colleague assigns it to F1, when the F1 is not an unmodified F1. Instead, it points to the W1.inner function address. And then call the F1 function, it is good to perform permission validation first, then call the original F1 (), where the F1 is passed through the parameters F1.

Timing of execution

 def   W1 (fun):  print  ("   ... Decorators Start decorating ...   " )  def   inner ():  print  ( '   ... Verify Permissions ...   " ) fun ()  return   Inner@w1  def   Test ():  print  ( " test  Span style= "COLOR: #800000" > " ) test ()  

Output Result:

... Decorators Start decorating ... Verify Permissions ... test

Thus, executing @w1 is equivalent to executing the following code:

Test = W1 (test)

Two adorner execution flow and cosmetic results

defMakebold (fun):Print('----a----')    definner ():Print('----1----')        return '<b>'+ Fun () +'</b>'    returnInnerdefmakeitalic (fun):Print('----b----')    definner ():Print('----2----')        return '<i>'+ Fun () +'</i>'    returnInner@makebold@makeitalicdefTest ():Print('----C----')    Print('----3----')    return 'Hello python decorator'ret=Test ()Print(ret)

Output Result:

----b--------a--------1--------2--------C--------3----<b><i>hello python decorator</i></b >

It can be found that the second adorner (makeitalic) is used to decorate, then decorate with the first adorner (Makebold), and the first adorner (Makebold) is executed during the call, followed by the second adorner (makeitalic).

Decorating with parametric functions

defW_say (fun):"""if the original function has parameters, the closure function must keep the number of arguments consistent and pass the arguments to the original method"""    defInner (name):"""if the decorated function has a row parameter, then the closure function must have parameters:p Aram Name:: return:"""        Print('say inner called') Fun (name)returnInner@w_saydefHello (name):Print('Hello'+name) Hello ('Wangcai')

Output Result:

Say Inner Calledhello Wangcai

Multiple parameters or a variable parameter

defW_add (func):defInner (*args, * *Kwargs):Print('add inner called') func (*args, * *Kwargs)returnInner@w_adddefAdd (A, b):Print('%d +%d =%d'% (A, B, a +b)) @w_adddefAdd2 (A, B, c):Print('%d +%d +%d =%d'% (A, B, C, a + B +c)) Add (2, 4) ADD2 (2, 4, 6)

Output Result:

add inner called2 + 4 = 6add inner called2 + 4 + 6 = 12

Modifying a function with a return value

defW_test (func):definner ():Print('w_test inner called start') func ()Print('w_test inner called End')    returninner@w_testdefTest ():Print('This is the test fun')    return 'Hello'ret=Test ()Print('ret value is%s'% ret)

Output Result:

is is None 

It can be found that at this time, there is no output of the test function ' Hello ', but none, that is why, it can be found that the inner function in the call to test, but not accept the return value, and do not return, then the default is None, know the reason, So let's change the code:

defW_test (func):definner ():Print('w_test inner called start') Str=func ()Print('w_test inner called End')        returnStrreturninner@w_testdefTest ():Print('This is the test fun')    return 'Hello'ret=Test ()Print('ret value is%s'% ret)

Output Result:

is is Hello 

Adorner with parameters

defFunc_args (pre='Xiaoqiang'):    defW_test_log (func):definner ():Print('... Logging ... visitor is%s'%pre) func ()returnInnerreturnW_test_log#An adorner with parameters can play at run time with different functions#executes Func_args (' Wangcai ') first, returning a reference to the W_test_log function#@w_test_log#decorate the test_log with @w_test_log@func_args ('Wangcai')defTest_log ():Print('This is test log') Test_log ()

Output Result:

is is test log 

General Purpose Decorators

defW_test (func):defInner (*args, * *Kwargs): Ret= Func (*args, * *Kwargs)returnretreturninner@w_testdefTest ():Print('Test called') @w_testdeftest1 ():Print('Test1 called')    return 'python'@w_testdefTest2 (a):Print('test2 called and value is%d'%a) test () test1 () test2 (9)

Output Result:

 and  is

Class Decorator

The adorner function is actually an interface constraint, which must accept a callable object as a parameter and then return a callable object.
In Python, general callable objects are functions, but there are exceptions. For example, if an object overrides the call method, then the object is callable.

When an object is created and executed directly, the exception is thrown, because he is not callable and cannot be executed directly, but after making the modification, it can execute the call directly, as follows

class Test (object):     def __call__ (Self, *args, * *Kwargs)        : Print ('callcalled'= Test ()print(t ())

Now, let's take a look at how to use the class decorator function.

classTest (object):def __init__(Self, func):Print('Test init')        Print('func name is%s'% func.__name__) self.__func=funcdef __call__(Self, *args, * *Kwargs):Print('functions in the adorner') self.__func() @TestdefTest ():Print('This is test func') test ()

Output Result:

is is test func 

As with the previous principle, when the Python interpreter executes to @test, the current test function is passed as a parameter to the test object, the Init method is called, and the test function is pointed to the created Test object, and then when the test () is executed, The call method is actually called directly to the object being created.

Python decorator @property

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: 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.