Understanding and advanced of the Adorner (Decorator) in Python

Source: Internet
Author: User

Sometimes some of the features in our project are modified to add some additional functionality to some of the internal functions, but for security reasons you don't want to change the source code of the function and the way the function is called, the adorner will help us a lot in this place.

Adorner (Decorator): (also called grammatical sugar)

Definition: The essence is a function, the function (decoration of other functions) is to add additional functions for other functions

Principle: (1). Cannot modify the source code of the decorated function

(2). Cannot modify the calling method of the decorated function

1. First to implement a simple adorner example:

#!/usr/bin/env python#-*-coding:utf-8-*-#定义一个简单的装饰器def simple_wrapper (func): Def wrapper (): Print ("I am an adorner, I use it to install Trim%s "% func.__name__) func () return wrapper# need to decorate the function @simple_wrapperdef Say_hello (): Print (" Hello World ") #执行say The _hello () function Say_hello () "Runs the result as follows: I am the decorator, I used to decorate Say_hellohello world"

The above implements a simple adorner that can be used to decorate a function without parameters, and with this simple example, we probably have a general understanding of the basic implementation of the adorner. But if you want to fully understand and master the principle of decoration, it is necessary to understand and master the concepts of higher-order functions, nested functions, and functions as "variables" in Python. Below I will give an example of the adorner and related content.

2. The above implements a simple adorner that can decorate without parameters, but under normal circumstances, our functions need to pass in the appropriate parameters, how can we implement the method to decorate the parameters?

#!/usr/bin/env python#-*-coding:utf-8-*-def simple_wrapper (func): Def wrapper (*args, **kwargs): print ("I am the decorator, I used to decorate the%s method "% func.__name__" func (*args, **kwargs) return wrapper@simple_wrapperdef Say_hello (name): Print ("H Ello ", name) #执行say_hello () function Say_hello (" Jack ") ' Run Result: I am the decorator I used to decorate the Say_hello method Hello Jack ' #是不是同样很简单呢? This method can be used to decorate functions with arbitrary parameters or to decorate functions without parameters.

3. The upper adorner has already been able to implement the basic requirements, that is, you can complete the function of adding additional functions to the specified functions, but at certain times, we need the adorner itself with the parameters, how to implement it?

#!/usr/bin/env python#-*-coding:utf-8-*-def my_wrapper (args): Print ("My parameters are:", args) def simple_wrapper (func):        def wrapper (*args, **kwargs): print ("I am the decorator I used to decorate the%s method"% func.__name__) func (*args, **kwargs) Return wrapper return Simple_wrapper @my_wrapper ("simple") def Say_hello (name): Print ("Hello", name) #执行say_hell O () function Say_hello ("Jack") Run Result: My parameters are: simple I am the decorator, I used to decorate Say_hello method Hello Jack "

Isn't it the same simple?

Simplicity is simple, but how does the key decorator implement adding additional functionality to other functions? How does the upper function work? Here's a simple example:

#!/usr/bin/env python#-*-coding:utf-8-*-def simple_wrapper (func): Def wrapper (*args, **kwargs): print ("I am the decorator,     I used to decorate the%s method "% func.__name__" func (*args, **kwargs) return wrapper def Say_hello (name): Print ("Hello", name) Say_hello = Simple_wrapper (Say_hello) #这里就等同于 the role of @simple_wrapper # is actually the equivalent of Say_hello=wrappersay_hello ("Jack") #所有 When executing Say_hello ("Jack"), the wrapper ("Jack") function is quite called

Simple explanation: You can see that the top can also implement the function of the adorner, the example is briefly analyzed: because the function as an object in Python, but also can be regarded as a "variable", not only can you assign the function name to other variables, you can also pass the function name as a parameter to other functions, You can also use the function name as the return value. (Popular point can say that, is the function name in memory is a memory address, it points to the memory address space of the function body, so you can use the function name as a "variable" to do the related operation, when the function name "variable" is added () when it becomes a function call, will execute the function body. In the small example above, when performing Say_hello = Simple_wrapper (Say_hello) This step, the function name Say_hello as a parameter to the functions Simple_wrapper (), but then the function simple_ Wrapper () returns the intrinsic function wrapper as the return value, and then Say_hello "re-copied", which Say_hello points to the memory space of the wrapper function body, and then executes Say_hello ("Jack") is equivalent to executing wrapper ("Jack").

4. Through the above example we will find that when using the adorner, the function Say_hello is actually replaced by the Simple_wrapper, it is taken for granted that its __name__ and other information has become the Simple_wrapper function information. How can a function be decorated without changing its own information? In fact, in Python provides a functools.wraps, and wraps is also an adorner, it is the function of the implementation of this function.

#!/usr/bin/env python# -*- coding:utf-8 -*-"Def simple_wrapper (func):     def wrapper (*args, **kwargs):         print (" I'm the decorator I used to decorate the%s method " % func.__name__"         func (*args, ** Kwargs)     return  wrapper@simple_wrapperdef say_hello (name):     print ("Hello", name) #输出say_hello现在的__name___属性print (say_hello.__name__)    #输出结果为: Wrapper " ' ##### #使用functools. Wrapsfrom functools import wrapsdef simple_wrapper (func):      @wraps (func)     def wrapper (*args, **kwargs):         print ("I am the decorator I used to decorate the%s method"  % func.__name__)          func (*args, **kwargs)     return  wrapper@simple_ Wrapperdef say_hello (name): &NBsp;   print ("Hello", name) #输出say_hello现在的__name__属性print (say_hello.__name__)    #输出结果为: Say_hello

5. In fact, a function can define multiple adorners at the same time, when a function defines multiple adorners, the order in which the adorner executes is the first layer of the adorner that performs the last call to the outermost adorner, and a simple example:

@a@b@cdef Say_hello (): pass# the order in which adorners are executed in this example is C > B > C (equivalent to a (b (c (Say_hello)))


Understanding and advanced of the Adorner (Decorator) in Python

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.