I often talk about the Python advanced decorator and the python advanced decorator.

Source: Internet
Author: User

I often talk about the Python advanced decorator and the python advanced decorator.

Functions are also objects

To understand the Python modifier, you must first understand that in Python, a function is also an object. Therefore, you can regard the function name when defining a function as a reference to a function object. Since it is a reference, you can assign a function to a variable, or pass or return a function as a parameter. You can also define functions in the function body.

Decorator nature

You can write a pure function example to restore what the decorator is doing.

def decorator(func):    def wrap():    print("Doing someting before executing func()")    func()    print("Doing someting after executing func()")  return wrapdef fun_test():  print("func")fun_test = decorator(fun_test)fun_test()# Output:# Doing someting before executing func()# func# Doing someting after executing func()

The reference of the function pointed to by fun_test is passed to the decorator () function.

The decorator () function defines the wrap () subfunction, which calls the fun_test () function passed in through func reference, some other things were done before and after the function was called.

The decorator () function returns the internally defined wrap () function reference.

Fun_test receives the function reference returned by decorator () and points to a new function object.

Use fun_test () to call the new function to execute the wrap () function, thus completing the decoration before and after the fun_test () function.

Decorator used in Python

In Python, you can use the @ symbol to conveniently use the decorator function.

def decorator(func):    def wrap():    print("Doing someting before executing func()")    func()    print("Doing someting after executing func()")  return wrap@decoratordef fun_test():  print("func")fun_test()# Output:# Doing someting before executing func()# func# Doing someting after executing func()

The decoration function has been implemented, but the following code is executed:

 

print(fun_test.__name__)# Output:# wrap

Fun_test. _ name _ has been changed to wrap. This is because the wrap () function has rewritten our function name and annotation document. You can solve this problem through functools. wraps. Wraps is decorated by a function, and supports copying function names, commenting documents, parameter lists, and other functions. This allows us to access the attributes of the function before decoration in the decorator.

More standardized writing:

from functools import wrapsdef decorator(func):  @wraps(func)  def wrap():    print("Doing someting before executing func()")    func()    print("Doing someting after executing func()")  return wrap@decoratordef fun_test():  print("func")fun_test()print(fun_test.__name__)# Output:# Doing someting before executing func()# func# Doing someting after executing func()# fun_test

Decorator with Parameters

By returning a function of the wrap function, you can simulate the wraps decorator and construct a decorator with parameters.

from functools import wrapsdef loginfo(info='info1'):  def loginfo_decorator(func):    @wraps(func)    def wrap_func(*args, **kwargs):      print(func.__name__ + ' was called')      print('info: %s' % info)            return func(*args, **kwargs)    return wrap_func  return loginfo_decorator  @loginfo()def func1():  pass  func1()# Output:# func1 was called# info: info1@loginfo(info='info2')def func2():  passfunc2()# Output:# func2 was called# info: info2

Decorations

By writing classes, you can also implement the decorator and make the decorator more practical in inheritance and other object-oriented features.

First, write a base class for the decorator:

From functools import wrapsclass loginfo: def _ init _ (self, info = 'info1'): self.info = info def _ call _ (self, func ): @ wrap def wrap_func (* args, ** kwargs): print (func. _ name _ + 'was called') print ('info: % s' % self.info) self. after () # Call The after method. You can implement return func (* args, ** kwargs) return wrap_func def after (self) in the subclass ): pass @ loginfo (info = 'info2 ') def func1 (): pass # Output: # func1 was called # info: info1

Inherit the loginfo class to extend the functions of the decorator:

class loginfo_after(loginfo):  def __init__(self, info2='info2', *args, **kwargs):    self.info2 = info2    super(loginfo_after, self).__init__(*args, **kwargs)  def after(self):    print('after: %s' % self.info2)@loginfo_after()def func2():  passfunc2()  # Output:# func2 was called# info: info1# after: info2

The above is a common example of the Python advanced modifier, which is all the content shared by the editor. I hope to give you a reference and support for the house of friends.

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.