Python multiple adorners in sequence reprint

Source: Internet
Author: User

Tag: The evaluation method is implemented according to the Int targe params HTTP function function

Original link: Http://www.cnblogs.com/nisen/p/6193426.html?utm_source=itdadao&utm_medium=referra

Adorners are the tools that Python uses to encapsulate functions or code, and there are many articles on the web that can be learned, and what I'm going to discuss here is a myth about the sequence of multiple adorners.

Questions

Most of the sequence of function calls involving multiple adorner decorations will indicate that they are top-down, such as the following example:

DefDecorator_a(func):Print' Get in Decorator_a 'DefInner_a(*args, **kwargs):Print' Get in Inner_a 'return func (*args, **kwargs)Return inner_aDefdecorator_b (func): print  ' Get in Decorator_b ' def inner_b (*args, **kwargs): print " Get in Inner_b ' return func (*args, **kwargs)  return Inner_b @decorator_b  @decorator_a def f (x): print  ' Get in F ' return x * 2f (1)         

The above code first defines the two functions: decotator_a, decotator_b , the function of the two functions is to receive a function as a parameter and then return the creation of another function, in the creation of the function called the received function (text than the code around the person). The last defined function f takes the decotator_a, decotator_b decoration function as defined above. What is the order after we call the decorated function with 1 parameters f decotator_a, decotator_b (here, in order to indicate the order in which the functions are executed, to see the order in which the functions are executed in the print output)?

If you judge a word by the bottom-up principle without thinking it, then execute it first, then output it, then decorator_a decorator_b output it Get in decotator_a Get in inner_a Get in decotator_b Get in inner_b . But that is not the case.

The results are actually running as follows:

Get in decorator_aGet in decorator_bGet in inner_bGet in inner_aGet in f
The difference between a function and a function call

Why do we do it first inner_b inner_a ? To get a thorough view of the above problem, you need to distinguish between two concepts: function and function invocation. In the above example, it is called a function f f(1) call, which is the result of evaluating the parameters passed in the former. In Python, the function is also an object, so f it refers to a function object, its value is the function itself, f(1) is a call to the function, its value is the result of the call, here the value of the 2 under the definition f(1) . Similarly, with the function above, decorator_a it returns a function object inner_a , which is defined internally by the function object. The inner_a function is called in func , func returning the result of the call as a value.

The adorner function executes immediately after being defined by the decorator function.

A second problem to be cleared up is what happens when the adorner decorates a function. Now simplify our example, assuming this is the following:

def decorator_a print  ' Get in Decorator_a ' Span class= "hljs-function" >def inner_a  (*args, **kwargs): print  ' Get in Inner_a ' return func (*args, **kwargs) return Inner_a @decorator_a def f (x): print  ' Get in F ' return x * 2    

As many of the articles introducing adorners say:

@decorator_adef f(x): print ‘Get in f‘ return x * 2# 相当于def f(x): print ‘Get in f‘ return x * 2f = decorator_a(f)

So, when the interpreter executes this code, decorator_a it has been called, it f returns a function as a function parameter, so it f is returned decorater_a inside inner_a . So when called later f , actually the equivalent of the call inner_a , f the passed parameter is passed inner_a , the inner_a received parameter will be passed in the call, inner_a and the func f last return is the f call Value, so it looks like a direct call on the outside f .

Explanation of the question

When the above two concepts are cleared, it is clear to see what is happening in the original example.
When the interpreter executes the following code, the   is actually called in sequence from bottom to top, decorator_a   and   decorator_b   , this will output the corresponding   get in Decorator_a   and   get in Decorator_b  . This time   F   is already equivalent to   decorator_b     inner_b  . But because   F   is not called, so   inner_b   does not call, and so on   Inner_b   internal   inner_a   not called, so   get in Inner_a   and   get in Inner_ b   will not be output.

@decorator_b@decorator_adef f(x): print ‘Get in f‘ return x * 2

And then the last line when we call the f incoming parameter 1, inner_b it is called, it prints first Get in inner_b , and then it is inner_b called internally inner_a so it will be printed again Get in inner_a , and then the inner_a original is called internally, and the f result is The final return. At this point you should know why the output would be that way, and what actually happened to the adorner execution order.

When we get rid of the last line in the example above and put it in the f repl, we can also see the order problem naturally:

? Test git: (Master)? Pythonpython2.7.11 (Default, Jan222016,08:29:[GCC]4.2.1 Compatible Apple LLVM7.0.2 (clang-700.1.81)]On Darwintype"Help","Copyright","Credits"Or "license" for more information.>>> import Test13get in decorator_aGet in decorator_b>>> test13.f (1) Get Span class= "Hljs-keyword" >in inner_bget in Inner_aget in f2>>> test13.f (2) get in inner_b Get in inner_aget in F4>>>            

In the actual application scenario, when we use the above method to write two decorative methods such as verifying that there is no login @login_required , and then verify that the permissions are not enough @permision_allowed , we use the following order to decorate the function:

@login_required@permision_alloweddef f()  # Do something return

Python multiple adorners in sequence reprint

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.