An example is provided to illustrate how to install the modifier in Python and how to use python.

Source: Internet
Author: User
Tags python decorator

An example is provided to illustrate how to install the modifier in Python and how to use python.

A function is also an object, and a function object can be assigned to a variable. Therefore, a function can also be called through a variable.

>>> def now():...   print '2013-12-25'...>>> f = now>>> f()2013-12-25

The function object has a _ name _ attribute. You can get the function name:

>>> now.__name__'now'>>> f.__name__'now'

Now, let's assume that we want to enhance the functions of the now () function, for example, to automatically print logs before and after the function call, but do not want to modify the definition of the now () function, this way of dynamically adding features during code execution is called the Decorator ).

In essence, decorator is a high-level function that returns a function. Therefore, we need to define a decorator that can print logs, which can be defined as follows:

def log(func):  def wrapper(*args, **kw):    print 'call %s():' % func.__name__    return func(*args, **kw)  return wrapper

Observe the preceding log. Because it is a decorator, a function is accepted as a parameter and a function is returned. We need to use the @ Syntax of Python to place the decorator in the definition of the function:

@logdef now():  print '2013-12-25'

Calling the now () function not only runs the now () function itself, but also prints a line of log before running the now () function:

>>> now()call now():2013-12-25

Put @ log in the definition of the now () function, which is equivalent to executing the statement:

now = log(now)

Because log () is a decorator and returns a function, the original now () function still exists, but now the now variable with the same name points to the new function, so now () is called () the new function will be executed, that is, the wrapper () function returned in the log () function.

The Parameter definition of the wrapper () function is (* args, ** kw). Therefore, the wrapper () function can call any parameter. In the wrapper () function, first print the log and then call the original function.

If the decorator itself needs to input parameters, you need to write a high-order function that returns the decorator, which is more complex to write. For example, to customize the log text:

def log(text):  def decorator(func):    def wrapper(*args, **kw):      print '%s %s():' % (text, func.__name__)      return func(*args, **kw)    return wrapper  return decorator

The three-layer nested decorator usage is as follows:

@log('execute')def now():  print '2013-12-25'

The execution result is as follows:

>>> now()execute now():2013-12-25

Compared with the two-layer nested decorator, the effect of layer-3 Nesting is as follows:

>>> now = log('execute')(now)

Let's analyze the preceding statement. First, execute log ('execute '), return the decorator function, and then call the returned function. The parameter is the now function, and the returned value is the wrapper function.

The definition of the above two types of decorator is correct, but the last step is poor. Because the function is also an object, it has attributes such as _ name _, but you can see the function after decorator decoration, their _ name _ has changed from the original 'now 'to 'wrapper ':

>>> now.__name__'wrapper'

Because the returned wrapper () function name is 'wrapper', You need to copy the _ name _ attributes of the original function to the wrapper () function. Otherwise, some code execution that depends on the function signature will fail.

No need to write wrapper. _ name _ = func. python built-in functools. wraps does this. Therefore, a complete decorator statement is as follows:

import functoolsdef log(func):  @functools.wraps(func)  def wrapper(*args, **kw):    print 'call %s():' % func.__name__    return func(*args, **kw)  return wrapper

Or for the decorator with parameters:

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 decorator

Import functools is to import the functools module. The concept of the module will be explained later. Now, remember to add @ functools. wraps (func) before defining wrapper.
Summary

In the object-oriented (OOP) design pattern, decorator is called the decoration pattern. The decoration mode of OOP needs to be implemented through inheritance and combination. In addition to the decorator that supports OOP, Python directly supports decorator at the syntax level. Python decorator can be implemented using functions or classes.

Decorator can enhance functions of functions. Although it is a bit complicated to define, It is very flexible and convenient to use.

Compile a decorator to print logs of 'begincall' and 'end call' before and after function calling.

Think about whether to write a @ log decorator so that it supports both:

@logdef f():  pass

It also supports:

@log('execute')def f():  pass

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