Python decorator (decorator) Definition and Usage Details, pythondecorator

Source: Internet
Author: User
Tags python decorator

Python decorator (decorator) Definition and Usage Details, pythondecorator

This article describes the definition and usage of the Python decorator. We will share this with you for your reference. The details are as follows:

What is decorator)

To put it simply, you can think of the decorator as a function for packaging functions. It generally processes the passed functions or classes and returns the modified objects. therefore, we can execute other code before and after executing the original function without modifying the original function. common scenarios include log insertion and transaction processing.

Decorator

The simplest function returns the sum of two numbers

def calc_add(a, b): return a + bcalc_add(1, 2)

But now there are new requirements. It is very easy to calculate the sum operation. Get the time before the sum, and then get the sum again. Just calculate the difference.

import datetimedef calc_add(a, b): start_time = datetime.datetime.now() result = a + b end_tiem = datetime.datetime.now() print "result:", result, "used:", (end_tiem - start_time).microseconds, "μs" return resultcalc_add(1, 2)

Now, the functioncalc_diff(a, b), Calculate a-B, and also want to calculate the time difference of the subtraction operation, it is easy to do, copy that piece of code. however, if we want to compile a mathematical function library and all functions want to calculate the execution time, We can't copy the code one by one, so we can look for a better solution.

As we know, in Python, functions are also considered objects and can be passed as parameters. Therefore, if we separate computing time consumption into a separate functioncalc_spend_time()Then, pass the reference of the function that needs to calculate the time consumption, such as calc_add, and call calc_add in calc_spend_time. In this way, all the functions that need to calculate the time consumption do not need to modify their own code.

def calc_spend_time(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"def calc_add(a, b): return a + bcalc_spend_time(calc_add, 1, 1)# calc_spend_time(calc_add, a=1, b=2)

It looks good. The function responsible for computing does not need to be changed. You only need to pass the function as a parameter to the function for calculating the time difference. however, the form of the call has changed. Instead of clac (1, 2), it is calc_spend_time (clac_add, 1, 2). In case calc_add is called on a large scale, it is still very troublesome to find and modify it in one place. if you do not want to modify the code, you haveclac()Andcalc_spend_time(clac)The effect is the same.calc_spend_time()Package the passed clac, then return the new function after packaging, and then assign the returned function to clac. Then the effect of calc () is the same as that in the previous example.calc_spend_time(calc())Same effect.

import datetimedef 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_funcdef calc_add(a, b): return a + bcalc_add = calc_spend_time(calc_add)calc_add(1, 2)

Syntactic sugar

The above example is the decorator concept, and the function of function packaging. In fact, the above example can be simplified.

import datetimedef 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@calc_spend_timedef calc_add(a, b): return a + bcalc_add(1, 2)

@calc_spend_timeIt is syntactic sugar. Its essence is:calc_add = calc_spend_time(calc_add)

Parameter-free function decorator

import datetimedef 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_timedef calc_add(a, b): return a + b@calc_spend_timedef calc_diff(a, b): return a - bcalc_add(a=1, b=2)calc_diff(1, 2)

Note:

* Args: package all parameters into a list in the order of appearance.
** Kargs: Pack all parameters in the key = value form into a dict.

Function decorators with Parameters

If we need to know some additional information about the function, such as the function author, we can add parameters to the decoration function.

import datetimedef 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"  return new_func return 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 - bcalc_add(a=1, b=2)calc_diff(1, 2)

Python built-in decorator

Python has three built-in decorators:Staticmethod,ClassmethodAndProperty.

Staticmethod: Defines a method in a class as a static method. A method decorated with staticmethod can be called using an instance object of a class or class, without passing in 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 helloI say hi

Classmethod: Defines a method in a class as a class method. The classmethod decoration method can be called using the class or class instance object, and the class object is implicitly passed as the first parameter.

class Human(object): """docstring for Human""" def __init__(self):  super(Human, self).__init__()  self.message = '111' def say(message):  if not message:   message = 'hello'  print 'I say %s' % message @classmethod def speak(cls, message):  if not message:   message = 'hello'  cls.say(message)human = Human()human.speak('hi')

Output example above

Property: Convert a method to an attribute.

class Human(object): """docstring for Human""" def __init__(self, value):  super(Human, self).__init__()  self._age = value @property def age(self):  return self._agehuman = Human(20)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.