Python Learning note __4.4 decorator (add extra features)

Source: Internet
Author: User

# This is a learning note for the Liaoche teacher Python tutorial

1. Overview

Adorners can help us add extra functionality to objects that already exist

An adorner is essentially a Python function that allows other functions to add extra functionality without any code changes, and the return value of the adorner is also a function object.

Adorners are often used in scenarios where there is a need for facets, such as inserting logs, performance testing, handling of things, caching, permission checking, and so on.

1.1. Add a row of logs for the now function

# define NOW function

def now ():

Print (' 2018-5-8 ')

# Edit Decorator

def log (func): # Accept the function of the name

def wrapper (*args,**kw): # receive parameters for incoming functions

print (' The function name is%s (): '% func.__name__) # Print the __name__ property of the function , note that __name__ is two _ ( Underline )

return func (*ARGS,**KW) # returns this function

Return wrapper

# Add decorator to the NOW function

@log

def now ():

Print (' 2018-5-8 ')

Placing the @log at the definition of the now () function is equivalent to executing the now=log. The procedure is "Wapper=log (now), Weapper returns now ()"

Since log () is a decorator that returns a function, the original now () function still exists, but the current variable with the same name currently points to the new function, and then the new function will be executed , i.e. the log () The wrapper () function returned in the function.

1.2, three-layer nested decorator

If the decorator itself needs to pass in parameters, it is necessary to write a higher-order function that returns decorator. For example, to customize the text of a log

def log (text):

def decorator (func):

def wrapper (*args, **kw):

Print ('%s%s (): '% (text, func.__name__))

return func (*args, **kw)

Return wrapper

return decorator

# Added to the now () function

@log (' Execute ')

def now ():

Print (' 2015-3-25 ')

# effect

>>> Now ()

Execute Now ():

2015-3-25

Three-layer nested execution effect: now = log (' Execute ') (now)

1.3. Property copy of primitive function

As can be seen from the above example, the now () function is ultimately returned by the wrapper function. The __name__ property of the Now () function has changed to ' wrapper '

>>> now.__name__

' Wrapper '

But our intention is only to add extra functionality to the now () function, and not to change its own properties, then we need to copy the properties of the () function to the wrapper () function

There's no need to write code like wrapper.__name__ = func.__name__, and Python's built-in functools.wraps is doing it.

functools.wraps:wraps itself is also an adorner, which can copy the meta-information of the original function into the adorner function . This allows the adorner function to have the same meta-information as the original function

# By the way, copy the property's decorator

Import Functools

def log (func):

@functools. Wraps (func) # This adorner is always above the wrapper function

def wrapper (*args, **kw):

Print (' Call%s (): '% func.__name__)

return func (*args, **kw)

Return wrapper

2. Example

1, please design a decorator, it can be used for any function, and print the function execution time:

#-*-Coding:utf-8-*-
Import time, Functools

def metric (FN):

@functools. Wraps (FN) # Copy the original function information to wrapper

def wrapper (*args, **kw):

Begin=time.time ()

Res=fn (*args, **kw) # Assign The return value of the FN function to res

End=time.time ()

print ("%s executed in%s MS"% (fn.__name__, (End-start) *1000)) # print Execution time Ms

return res

Return wrapper

2, before and after the execution of the function to print marks

def log (func):

def call (*ARGS,**KW):

Print (' Begin call ')

Out=func (*args,**kw) # The key is to assign the return value of a function to a variable, and the last return variable

Print (' End call ')

Return out

Return call


Python Learning note __4.4 decorator (add extra features)

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.