Python Decorator Basics

Source: Internet
Author: User

Transferred from: http://www.cnblogs.com/xybaby/p/6274187.html

Generally speaking An adorner is a function that takes a function (or class) as a parameter, and the return value is also a function (or class)。 Let's start with a simple example:
#-*-coding:utf-8-*-2def log_cost_time (func):3def wrapped (*args, * *Kwargs):4Import Time5Begin =time.time ()6         Try: 7             returnFunc (*args, * *Kwargs)8         finally: 9Print'func%s cost%s'% (func.__name__, time.time ()-begin)Ten     returnWrapped One  A@log_cost_time -def complex_func (num): -RET =0 the      forIinchxrange (num): -RET + = i *I -     returnret -#complex_func =log_cost_time (Complex_func) +  - if__name__ = ='__main__': +Print Complex_func (100000) Copy the code
View Code

In the code, the function log_cost_time is an adorner, its function is also very simple, printing is decorated function run time.

The adorner's syntax is as follows:
1 @dec 2     def func ():p

is essentially equivalent to: func = Dec (func).

In the code snippet 0 above, the Line12 is commented out and then the line18 annotation is removed, which is the same effect. In addition, Staticmethod and Classmethod are two adorners that we often used in the code, and if the PYC is deserialized, the resulting code is generally the Func = Staticmthod (func) pattern. Of course, the @ symbol is more popular in the form of at least one less spelling of the function name. adorners can be nested, such as @dec0 @dec1 def func ():p, and so will be in Func = DEC0 (DEC1 (fun)). Adorners also have "side effects", for the Complex_calc decorated by log_cost_time, we look at complex_func.__name__, the output is: "Wrapped" ". Well, this is the name of inner function (wrapped) inside the log_cost_time, and of course the caller wants the output to be "Complex_func", in order to solve this problem, Python provides two functions.
    • Functools.update_wrapper
Prototype: functools. update_wrapper( Wrapper, wrapped[, assigned][, updated]The third parameter, copy the value of wrapped directly to wrapper, default to (__doc__, __name__, __module__) fourth parameter, update, default = (__dict__)
    • Package of Functools.wraps:update_wrapper

  

 is  for Partial  as a function decorator when defining a wrapper function.

Simple Change Code:

1 Import Functools2 def log_cost_time (func):3 @functools. Wraps (func)4def wrapped (*args, * *Kwargs):5 Import Time6Begin =time.time ()7         Try:8             returnFunc (*args, * *Kwargs)9         finally:TenPrint'func%s cost%s'% (func.__name__, time.time ()-begin) One     returnWrapped

And look at the complex_func.__name__ output is "Complex_func"

adorners are also available with parameters.。 Let's modify the above code slightly:
1 def log_cost_time (stream):2 def Inner_dec (func):3def wrapped (*args, * *Kwargs):4 Import Time5Begin =time.time ()6             Try:7                 returnFunc (*args, * *Kwargs)8             finally:9Stream.Write ('func%s cost%s \ n'% (func.__name__, time.time ()-begin))Ten         returnWrapped One     returnInner_dec A  - Import SYS - @log_cost_time (sys.stdout) the def complex_func (num): -RET =0 -      forIinchxrange (num): -RET + = i *I +     returnret -  + if__name__ = ='__main__': APrint Complex_func (100000)

The Log_cost_time function also accepts a parameter that specifies the output stream for the information, for decorator with parameters

@dec (Dec_args) def func (*args, **kwargs):p is equivalent to Func = Dec (Dec_args) (*args, **kwargs). Decorator's modification of a classis also very simple, but usually not used much. For example, we need to change the __str__ method of the class, the code is very simple.
1 def Haha (CLZ):2clz.__str__ = lambda s:"Haha"3     returnCLZ4 5 @Haha6 classWidgets (Object):7     " "class Widget" "8 9 if__name__ = ='__main__':TenW =widgets () OnePrint W

It is necessary to use decorator in any scenario, and a pattern in design mode is also called an adorner. Let's briefly review the adorner pattern in the design pattern, a simple sentence overview

Dynamically add additional responsibility to an object
Because the adorner mode only changes the component externally, the component does not need to have any knowledge of its decorations, which means that the decorations are transparent to the component.

Returning to Python, it is natural to implement the adorner pattern with the decorator syntax, such as the sample code in this article, which adds extra functionality to record function execution time without changing the decorated object. Of course, because of the flexibility of the Python language, decorator can modify objects that are decorated (such as examples of decorative classes). Decorator is very versatile in Python, here are a few things:

(1) Modify the properties or behavior of the decorated object (2) Handle the context that is executed by the function object, such as setting environment variables, plus log and so on (3) to handle the repetitive logic, such as n functions can run out of the exception, but we do not care about these exceptions, as long as the caller does not pass the exception to the line At this point, you can write a catchall decorator for the function that might run out of the exception.
def catchall (func):    @functools. Wraps (func)    def wrapped (*args, * *Kwargs)        :Try  :            return func (*args, * *Kwargs)        except:            pass    return Wrapped
Functional programming of the REFERENCESPEP 0318:https://www.python.org/dev/peps/pep-0318/#syntax-alternativespython modifier:/http Coolshell.cn/articles/11265.html

Python Decorator Basics

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.