Python Adorner (decorator) __python

Source: Internet
Author: User
Tags pack wrapper
what is an adorner (decorator)In short, the adorner can be interpreted as a function of the wrapper function, it generally will be passed in the function or class to do some processing, return the modified object. Therefore, we can execute other code before and after executing the original function without modifying the original function. More common scenarios include log insertion, transaction processing, and so on. Decorative DeviceThe simplest function, which returns a two-digit and
Def Calc_add (A, B): return
    A + b

calc_add (1, 2)
But now there are new requirements, calculate the sum operation time-consuming, very simple, before summing up the time, sum and then fetch again, the difference can be
Import datetime

def calc_add (A, B):
    start_time = datetime.datetime.now () result
    = a + b
    end_tiem = Dateti Me.datetime.now ()
    print ' Result: ', result, ' used: ', (end_tiem-start_time). microseconds, "μs" return
    result< C10/>calc_add (1, 2)
Now, the function Calc_diff (A, B), calculates the a-b, also wants to calculate the subtraction operation time difference, is very good to do, copies the code to the past.   But if we want to make up a mathematical function library now, all kinds of functions want to calculate its execution time, can not one copy code, think of a better way. We know that in Python functions are also treated as objects and can be passed as arguments, so if the computation takes time to be independent of a separate function calc_spend_time (), then pass the function that needs to compute time-consuming such as calc_add to it, in calc_ Call Calc_add in spend_time so that all functions that need to be computationally time-consuming do not have to modify their own code.
Def calc_spend_time (func, *args, **kargs):
    start_time = datetime.datetime.now () result
    = Func (*args, **kargs) C2/>end_tiem = Datetime.datetime.now ()
    print "Result:", result, "used:", (End_tiem-start_time). microseconds, "μs"


def calc_add (A, B): return
    A + b

calc_spend_time (Calc_add, 1, 1)
# calc_spend_time (Calc_add, a=1, b=2)
It also looks good, the function responsible for the calculation does not need to change, just call as a parameter to calculate the time difference function. But it is this, the call time form changed, no longer is CLAC (1, 2), but Calc_spend_time (Clac_add, 1, 2), in case Calc_add large-scale is called, then still have to find a place, and then modify it, still very troublesome. If you want to make the CLAC () and Calc_spend_time (CLAC) effect the same, you can wrap the incoming CLAC in Calc_spend_time () and return the wrapped new function. Then the returned wrapper function is assigned to CLAC, and the Effect of Calc () is the same as the Calc_spend_time (Calc ()) Effect of the previous example.
Import datetime

def calc_spend_time (func):
    def new_func (A, B):
        start_time = Datetime.datetime.now ()
        result = Func (A, b)
        End_tiem = Datetime.datetime.now ()
        print ' Result: ', result, ' used: ', (End_tiem-start_time). microseconds, "μs" return
    new_func

def calc_add (A, B): return
    A + b

calc_add = Calc_spend_time (calc_add )
Calc_add (1, 2)
Grammar SugarThe above example is the concept of the adorner, the function of the wrapper function. In fact, the above examples can be more streamlined
Import datetime

def calc_spend_time (func):
    def new_func (A, B):
        start_time = Datetime.datetime.now () Result
        = Func (A, b)
        End_tiem = Datetime.datetime.now ()
        print ' Result: ', result, ' used: ', (End_tiem-star T_time). Microseconds, "μs" return
    new_func

@calc_spend_time
def calc_add (A, B): return
    A + b

Calc_add (1, 2)
@calc_spend_time is the grammatical sugar, its essence is: Calc_add = Calc_spend_time (Calc_add) function Adorner with no parameters
Import datetime

def calc_spend_time (func):
    def new_func (*args, **kargs):
        start_time = Datetime.datetime.now () Result
        = Func (*args, **kargs)
        End_tiem = Datetime.datetime.now ()
        print "Result:" , result, "used:", (End_tiem-start_time). microseconds, "μs" return
    new_func

@calc_spend_time
def calc_ Add (A, B): return
    A + b


@calc_spend_time
def calc_diff (A, B): return
    a-b

calc_add (a=1, b=2) C15/>calc_diff (1, 2)
Note: *args: Pack all the parameters into the list in the order in which they appear **kargs: Pack all the Key=value form parameters into a dict function Adorner with parametersIf we need to know some additional information about a function, such as a function author, you can do this by adding parameters to the adorner function.
Import datetime

def calc_spend_time (author):
    def First_deco (func):
        def new_func (*args, **kargs)
            : Start_time = Datetime.datetime.now () result
            = Func (*args, **kargs)
            End_tiem = Datetime.datetime.now ()
            Print author, "Result:", result, "used:", (End_tiem-start_time). microseconds, μs
    First_deco


@calc_spend_time (' author_1 ')
def calc_add (A, B): return
    A + b


@calc_spend_time (' Author_2 ')
def Calc_diff (A, B): return
    a-b

calc_add (a=1, b=2)
Calc_diff (1, 2)
Python built-in AdornerPython has three built-in adorners: StaticmethodClassmethodAnd PropertyStaticmethod: The method in the class is defined as a static method, and the method using the Staticmethod decoration can be invoked using the class or the instance object of the class, without the need to pass in the self
Class Human (object): "" "
    docstring for Human" "
    def __init__ (self):
        super (Human, self). __init__ ()

    @ Staticmethod
    def Say (message):
        If not message: message
            = ' Hello '
        print ' I say%s '% message

    def speak (Self, message):
        self.say (message)

Human.say (None)
Human = Human ()
human.speak (' Hi ')
Output:
I say hello
I say hi
Classmethod: The method in the class is defined as a class method, and the method using the Classmethod decoration can be invoked using the class or the instance object of the class, and the class object is implicitly passed in as the first argument
Class Human (object): "" "
    docstring for Human" "
    def __init__ (self):
        super (Human, self). __init__ ()
        Self.message = ' A '

    def say (message):
        If not message: message
            = ' Hello '
        print ' I say%s '% message

    @c Lassmethod
    def speak (CLS, message):
        If not message: message
            = ' Hello '
        cls.say (message)


human = Human ()
human.speak (' Hi ')
Output above example
Property: Turn the method into a property
Class Human (object): "" "
    docstring for Human" "
    def __init__ (self, value):
        super (Human, self). __init__ ()
        self._age = value

    @property
    def Age (self): return
        self._age

human = Human
print Human.age

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.