Python's decorator Decorator

Source: Internet
Author: User
Tags define function

The recently seen Liaoche Python tutorial is a great boon for anyone learning Python, with no lengthy nonsense, only the most popular short words, and the clearest examples.

Here is my summary of this section of the adorner, as well as my own understanding.

Note: "The code in this article refers to the tutorial above"

Many times I would like to combine a lot of Python syntax with C + +, in C + +, the function name is the address of the function, we can be defined as a "function pointer" variable, and the function name assigned to the variable, then we call the function, we can directly use the variable call function.

For example, the following C + + code is the definition of a simple function pointer and the process of invoking it.

#include <iostream>using namespace Std;int f (int x, int y) {    return x+y;} int main (void) {    int (*fptr) (int,int);//define function pointer to make FPTR.    fptr = f;    cout << (*fptr) (2,3) << Endl;    return 0;}

In Python, a function is also an object, and a function object can be assigned to a variable. The function can also be called through this variable, as above. But Python is a dynamic language, not so complicated as to define the type of variable, just like the fptr above. You can assign values directly.

For example, the following simple Python code:

def date ():    print "2014-11-5" f = date//f is the function pointer date () f ()

The function object has a property __name__, which can get the name of the function: for example: f.__name__ is date.

below start to get to the point, decorator is what, Decorator is a high-order function that returns a function . For example, we have a simple log function that does the work of logging each time a function is called. But we don't want to change the implementation code for every function that needs to be counted into the log, so decorator comes in handy.

def log (func):    def wrapper (*args, **kw):        print "[log]: Call%s ():"%func.__name__        return func (*args, **kw) C8/>return Wrapper

First, the parameter of the function log above is a function object, and the return value is also a function.

So how do you use the log function? It is simple to use @log key sentence before the function definition to pass in the log as a parameter. That is, like this:

@log def date ():    print "2014-11-5"

So each call to date () is equivalent to calling log (date). Do not add @log statement before date, the result of the output is:

2014-11-5

The output after adding the @log statement is:

[log]: Call Date ()

2014-11-5

That is, after the log is added, the function's call is equivalent to log (date), and the log function's argument is date, which returns wrapper. As you can see, wrapper can accept any parameter function, inside the wrapper function, print the log line first, and then call the original function.

The simple answer here is that, before the function is called, if the package is made, that is, the @ keyword is used before the function definition, then we call the corresponding package function. For example, the call to date above is actually a log (date).

The possible problem here is that the function is an object and has a __name__ property, but you will find that the date function above is decorated with the __name__ property wrapper. This will cause problems with this __name__-dependent code, so what we need is the WRAPPER.__NAME__ = date.__name__ statement, which can be implemented in Python simply using the following code. The full version of the adornment function:

Import functoolsdef Log (func):    @functools. Wraps (func)    def wrapper (*args, **kw):        print "Call%s:"%func.__ name__        return func (*args, **kw)    return wrapper

The wraps function can be implemented using the module FUNCTOOLS.


The above describes the decorator pattern, the following gives a more complete example.

#!/usr/bin/env pythonimport sys#decoratorimport functoolsdef log (func):    @functools. Wraps (func)    def Wrapper (*args, **kw):        print "[log]: Call%s ():"%func.__name__        f = func (*args, **kw)        return F    return Wrappe Rdate () Print date.__name__

The code results output is:

[log]: Call Date ():

2014-11-5

Date


If the log function itself has parameters, then the decorator mode needs to add a layer of arguments to the log function itself, the code:

Import functoolsdef log (text):    def Decorator (func):        @functools. Wraps (func)        def wrapper (*args, **kw):            print '%s%s '% (text,func.__name__)            return func (*args, **kw)        return wrapper    return Decoratorprint "Test full implementation of decorator" @log (" Paramete of Log ") def date ():    print" 2014-11-5 "date ()


Calling the log function at this point is equivalent to calling log ("parameter of Log") (date), the return value of the function log is the decorator function, and the date is passed as a parameter to the Decorator function, which implements the call.

This concludes with one of the most complete examples:

#!/usr/bin/env pythonimport functoolsdef Log (text):    def Decorator (func):        @functools. Wraps (func)        def Wrapper (*args, **kw):            print "%s%s ()"% (text, func.__name__)            return func (*args, **kw)        return wrapper    Return Decoratordef log2 (func):    def decorator (*args, **kw): Return        func (*args, **kw)    return Decorator@log ("Decorator need parameter Version1") @log ("Decorator need parameter Version2") def date2 (x, y):    print "2014-11-5" C11/>print "x, Y", X, y    return xdate2 = log (' execute1 ') (date2) date2 = log (' Execute2 ') (date2) date2 = log (' Execute3 ') ( Date2) Date2 (2, 3)



The output is:

Execute3 Date2 ()

Execute2 Date2 ()

Execute1 Date2 ()

Decorator need parameter Version1 Date2 ()

Decorator need parameter Version2 Date2 ()

2014-11-5

X, y 2 3



Reference: Python's decorator






Python's decorator Decorator

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.